小米此次同时发布 MiMo-V2.6-Pro 和 MiMo-V2.6-Flash 两个原生全模态模型,但更值得工程团队关注的,是背后持续 6 天的 Live RL 训练。训练过程、成本信息、技术报告、强化学习代码和训练环境一并开放,让外部开发者有机会从“看榜单”进一步走到“审计训练方法、复现实验并评估投入产出比”。
这次开放为什么比单独发布权重更有价值
模型权重只能回答“最终得到了什么”,而训练代码、环境与成本记录可以帮助开发者继续追问:
- 强化学习阶段如何组织 rollout、奖励计算和参数更新;
- 训练过程中采用了什么评估与检查机制;
- 连续运行 6 天需要怎样的资源调度和故障恢复能力;
- 性能提升是否值得额外的训练、推理与运维成本;
- 哪些组件可以迁移到自己的领域模型,哪些部分依赖特定基础设施。
这也是 Live RL 的工程意义所在。它不只是把一次离线训练拉长,而是要维持数据生成、奖励反馈、策略更新和回归评估之间的闭环。任何一个环节不稳定,都可能让昂贵的算力被低质量样本、异常奖励或重复 rollout 消耗掉。
不过,开源代码不等于“一键复现”。复现前仍需核对模型许可证、训练数据依赖、硬件拓扑、并行策略、检查点格式以及外部服务。技术报告中的总成本也不能直接套用到另一套集群:GPU 型号、利用率、网络、失败重试和云资源定价都会改变结果。
Pro 与 Flash 不应只按名字做选择
两个模型同时发布,为生产系统提供了分层路由的可能,但不应未经测试就假设 Pro 一定适合所有复杂任务、Flash 一定适合所有低延迟任务。更稳妥的做法是建立同一套内部评测集,比较以下指标:
| 维度 | 建议记录的指标 |
|---|---|
| 质量 | 任务成功率、事实错误率、格式合规率 |
| 多模态 | 图像、文本等输入组合下的准确率与失败类型 |
| 延迟 | 首 token 延迟、完整响应时间、P95/P99 |
| 成本 | 单请求 token、GPU 时间或 API 费用 |
| 稳定性 | 超时率、空响应率、重复输出率 |
| 安全性 | 越权调用、敏感信息泄漏、提示注入成功率 |
一种可行的生产策略是:默认把请求交给成本较低的候选模型,当输入长度、任务类型或置信度触发阈值时,再升级到另一个模型。这里的路由规则必须由实测数据决定,而不是仅凭型号命名。
用统一脚本建立自己的对照实验
下面是一个可直接运行的最小评测脚本。它假设模型服务提供 OpenAI 兼容的 chat/completions 接口;这只是便于实践的接口假设,并不代表官方服务一定采用该协议。运行前需要按实际部署修改 BASE_URL、模型名称和认证信息。
将以下内容保存为 evaluate.py:
import json
import os
import time
import urllib.error
import urllib.request
BASE_URL = os.environ.get("BASE_URL", "http://127.0.0.1:8000/v1").rstrip("/")
API_KEY = os.environ.get("API_KEY", "")
MODELS = [m.strip() for m in os.environ.get(
"MODELS", "MiMo-V2.6-Pro,MiMo-V2.6-Flash"
).split(",") if m.strip()]
CASES = [
{
"id": "json-format",
"prompt": "只输出 JSON,给出字段 answer 和 reason:17 * 23 等于多少?",
},
{
"id": "instruction-following",
"prompt": "用三条要点解释什么是强化学习,每条不超过 20 个汉字。",
},
{
"id": "code-generation",
"prompt": "写一个 Python 函数,返回列表中出现次数最多的元素,并处理空列表。",
},
]
def call_model(model, prompt):
payload = {
"model": model,
"messages": [{"role": "user", "content": prompt}],
"temperature": 0,
}
headers = {"Content-Type": "application/json"}
if API_KEY:
headers["Authorization"] = f"Bearer {API_KEY}"
request = urllib.request.Request(
f"{BASE_URL}/chat/completions",
data=json.dumps(payload).encode("utf-8"),
headers=headers,
method="POST",
)
started = time.perf_counter()
with urllib.request.urlopen(request, timeout=120) as response:
result = json.loads(response.read().decode("utf-8"))
elapsed_ms = round((time.perf_counter() - started) * 1000, 1)
return {
"latency_ms": elapsed_ms,
"text": result["choices"][0]["message"]["content"],
"usage": result.get("usage", {}),
}
def main():
with open("results.jsonl", "w", encoding="utf-8") as output:
for model in MODELS:
for case in CASES:
record = {"model": model, "case_id": case["id"]}
try:
record.update(call_model(model, case["prompt"]))
print(model, case["id"], record["latency_ms"], "ms")
except Exception as exc:
record["error"] = repr(exc)
print(model, case["id"], "ERROR", exc)
output.write(json.dumps(record, ensure_ascii=False) + "\n")
output.flush()
if __name__ == "__main__":
main()
运行命令如下:
export BASE_URL="http://127.0.0.1:8000/v1"
export API_KEY="replace-with-your-token"
export MODELS="MiMo-V2.6-Pro,MiMo-V2.6-Flash"
python evaluate.py
脚本会把每个模型的响应、延迟和接口返回的 token 用量写入 results.jsonl。实际使用时,应把三个示例问题替换成脱敏后的真实业务样本,并加入确定性判分器、人工抽检和多轮重复测试。
对于图像、音频等全模态能力,不建议直接猜测请求字段。应先根据实际模型服务的接口文档确认媒体编码、大小限制和消息结构,再扩展测试集。否则,接口适配错误很容易被误判为模型能力不足。
从 Live RL 代码中优先检查什么
阅读开源强化学习实现时,可以沿着一条完整样本链路检查,而不是只关注优化器参数:
任务采样
-> 当前策略生成多个候选结果
-> 规则、验证器或奖励模型打分
-> 过滤异常与低信息样本
-> 计算优势并更新策略
-> 在固定评测集上做回归测试
-> 保存检查点,必要时回滚
建议重点核对四类问题:
- 奖励是否可被钻空子:格式分数、长度分数或单一验证器都可能诱导模型学习捷径。
- 训练数据是否持续漂移:在线生成的数据会随策略变化,早期和后期样本可能已不属于同一分布。
- 失败能否恢复:长时间训练必须能够从检查点恢复,并保存优化器、调度器和数据游标等状态。
- 评估是否与训练解耦:如果评测题或判分逻辑泄漏进训练闭环,分数上涨不代表泛化能力提升。
成本审计也应拆分为 rollout、奖励计算、训练更新、评估和失败重试,而不是只记录一个总 GPU 小时。这样才能判断优化缓存、减少候选数或更换验证器究竟能节省多少资源。
采用前的工程清单
MiMo-V2.6 的意义不仅是增加两个可选模型,也在于提供了一份更完整的 RL 工程观察样本。团队准备试用或复现时,可以按下面的顺序推进:
- 确认权重、代码和数据相关许可证是否覆盖预期用途;
- 先跑固定离线评测,再接入灰度流量;
- 用真实业务样本比较 Pro 与 Flash,不按名称预设结论;
- 分开记录推理、rollout、奖励和训练更新成本;
- 检查奖励投机、数据污染和评测泄漏;
- 为长时间训练配置检查点、监控、限额与自动回滚;
- 在启用全模态输入前完成隐私、内容安全和文件解析审计。
如果目标只是部署模型,权重和推理环境可能已经足够;如果目标是改造强化学习流水线,那么训练日志、成本拆分、代码与环境往往比单次榜单成绩更有参考价值。真正值得复用的,不只是最终检查点,而是能够被测量、定位和回滚的训练闭环。