| type | onboarding | ||||
|---|---|---|---|---|---|
| tags |
|
||||
| requires |
|
摘要:给已有模型增加一个新的 impl 时,优先复用现有 model family 的 config / registry / benchmark 入口,只把真正不同的实现部分拆出来。 前提:先确认这件事真的是“新 impl”,而不是给现有 impl 增加一个局部配置开关。 参考实现:
model/qwen3_moe/lite/protocol.py、model/qwen3_moe/hybrid/protocol.py、exp/bench_1n_bridge_lite_hybrid.sh
下面这些情况更适合做成一个新的 impl:
- 你想长期维护一条新的实现路线,例如
lite/hybrid/triton - 差异已经不只是一个局部开关,而是模型构造、checkpoint、训练栈接线中的一整组选择
- 你需要把 benchmark、回归验证和用户配置都按“另一套实现”来比较
下面这些情况通常先不要拆新 impl:
- 只是一个短期开关实验
- 只是现有 impl 内部的局部策略切换,且不会成为稳定对外选择
- 差异只存在于一个很窄的内部 helper,用户层面不需要感知
已有模型下新增 impl,优先沿用现有 model family:
model/my_model/
config.py
lite/
protocol.py
model.py
checkpoint.py
hybrid/
protocol.py
model.py
checkpoint.py
triton/
protocol.py
model.py
checkpoint.py
不是每个 impl 都必须把三份文件都重写一遍;如果 checkpoint 或 config 完全共用,就应显式复用,而不是复制一份相同代码。
- 先选一个最接近的新 impl reference,通常是现有
lite或hybrid - 优先复用同一 model family 下的
config.py - 在新 impl 的
protocol.py里只加入这个 impl 真正需要的ImplConfig字段 - 如果权重映射没变,尽量复用现有 checkpoint 逻辑
- 通过
register_model(..., impls={...})把新 impl 加到已有model_name下,而不是新造一个模型名
register_model(
"my_model",
package="my_repo.my_model",
hf_model_types=["my_model"],
impls={
"lite": "my_repo.my_model.lite.protocol",
"hybrid": "my_repo.my_model.hybrid.protocol",
"triton": "my_repo.my_model.triton.protocol",
},
)关键点:
- 新 impl 仍然属于同一个
model_name - impl 名字应该表达稳定实现路线,而不是一次性实验结论
- 不要为了“先跑通”把半成品 impl 暴露成长期公共名字
- 只暴露这个 impl 真正独有、且你愿意长期维护的字段
- 共用字段保持和已有 impl 一致,例如
parallel、optimizer、recompute - 如果某个能力当前未稳定支持,就不要先把 knob 占出来
一个实用标准是:用户是否真的需要在 bench / runtime 配置里显式选择它;如果不需要,先别公开。
新增 impl 后,验证顺序建议固定:
- 先跑这个 impl 的最小 BB case,确认能 build + run
- 再和已有 impl 做对比,例如
litevshybrid - 必要时再和
bridge做 baseline 对比 - 所有对比都尽量复用同一组输入规模和并行配置
如果要做多组 impl 对比,可以直接参考:exp/bench_1n_bridge_lite_hybrid.sh
- 新 impl 不等于新 model family;尽量复用已有 model family 的公共部分
- 不要因为新增 impl 就复制一整套完全相同的 config / checkpoint 代码
- 文档不规定哪种 impl 一定更快;这必须交给本地 benchmark
new_model:先把 model family 的最小版本建立起来benchmark:新增 impl 后的默认验证入口tune_speed:如果新增 impl 的目标主要是吞吐,再去看外部 speed skills