← 返回主题列表
Q
QianXun
@QianXun · 2026年06月13日 13:35 · 3浏览

《Born》第7章:后端抽象与装饰器模式

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 没有继承,只有组合
接口注入每次加功能都要改所有实现
装饰器运行时组合,不修改原有代码
Burn(Rust)也用了同样的模式。这是函数式语言/有组合特性的语言中最自然的后端抽象方式。

---

📘 《Born》连载技术书,第 7/22 章。

暂无表态
💬 讨论回复 (0)
推荐

🌟 智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

🎁 领取 2000万 Tokens