《Born》第7章:后端抽象与装饰器模式
Born 的 Backend 抽象是其架构的灵魂。它让同一套模型代码在不修改一行的情况下,运行在 CPU 和 GPU 上。
Born 的 Backend 抽象是其架构的灵魂。它让同一套模型代码在不修改一行的情况下,运行在 CPU 和 GPU 上。
装饰器模式:Backend 的栈式组合
// 基础后端
cpuBackend := cpu.New()
// 装饰器:自动微分
autodiffBackend := autodiff.New(cpuBackend)
// 装饰器:内存分析
profileBackend := profile.New(autodiffBackend)
// 最终后端 = 内存分析 → 自动微分 → CPU 计算
backend := profileBackend
装饰器模式的威力:你可以像搭积木一样组合后端能力。
Backend 接口
type Backend interface {
// 张量创建
Zeros(shape Shape) Tensor
Ones(shape Shape) Tensor
Randn(shape Shape) Tensor
// 逐元素运算
Add(a, b Tensor) Tensor
Sub(a, b Tensor) Tensor
Mul(a, b Tensor) Tensor
ReLU(x Tensor) Tensor
Sigmoid(x Tensor) Tensor
// 矩阵运算
MatMul(a, b Tensor) Tensor
Transpose(x Tensor) Tensor
// 形状操作
Reshape(x Tensor, shape Shape) Tensor
Squeeze(x Tensor) Tensor
// 归一化
LayerNorm(x Tensor, weight, bias Tensor, eps float32) Tensor
}
装饰器实现示例
// AutodiffBackend 包装另一个 Backend
type AutodiffBackend struct {
inner Backend
tape *Tape
}
func (b *AutodiffBackend) Add(a, b_ Tensor) Tensor {
result := b.inner.Add(a, b_)
b.tape.Record("Add", []Tensor{a, b_}, result)
return result
}
func (b *AutodiffBackend) MatMul(a, b_ Tensor) Tensor {
result := b.inner.MatMul(a, b_)
b.tape.Record("MatMul", []Tensor{a, b_}, result)
return result
}
每个算子调用都被记录到 tape 中,供反向传播时回放。
为什么要装饰器模式?
对比其他方案:
| 方案 | 问题 |
|---|---|
| 继承 | Go 没有继承,只有组合 |
| 接口注入 | 每次加功能都要改所有实现 |
| 装饰器 | 运行时组合,不修改原有代码 |
📘 《Born》连载技术书,第 7/22 章。