如何评价 Kimi 发布的多模态推理模型 k1.5?
很强。看榜单,作为一个多模态推理模型,在很多复杂推理任务benchmark上直接追平、甚至超过了o1,k1.5是有点东西的。
当然还有技术报告,昨晚熬夜读了一下(主要是抱着学习的心态),透露了很多技术细节和干货。不得不说是一份绝佳的研究推理模型的参考资料。
https://github.com/MoonshotAI/Kimi-k1.5/blob/main/Kimi_k1.5.pdf具体表现如何?
首先看一下Kimi k1.5的榜单数据。
根据思维链的长度,k1.5有long-COT和short-COT两个模式,其中后者是通过 long2short 方法(细节在后面),借助前者来改进得到的。
看了下论文中的数据,k1.5 short-COT在推理时所消耗的tokens数量跟常规大模型相近,但是它却拥有“思考”能力,因为本质还是有思维链,所以性能得到了提升,只是优化后步骤更少,token效率变高。
在 short-CoT 模式下,k1.5 在数学、代码、多模态和通用能力方面,都大幅超越了常规 SOTA 模型的水平,比如 GPT-4o 和 Claude 3.5 Sonnet。特别是AIME上,k1.5 得分 60.8 vs 4o 的 9.3,性能大幅领先。

在 long-CoT 模式下, k1.5 的数学、代码和多模态推理能力,也达到长思考 SOTA 模型 OpenAI o1满血版的水平。


可贵的是这份 25 页的技术报告,公开了k1.5从训练到部署阶段的诸多技术细节。

k1.5 技术细节
大家都知道Scaling law是个好东西,但是问题是它依赖海量数据,尤其是高质量数据,目前人类迄今为止所生产的高质量数据基本上已经被这些大模型公司扒完了,导致scaling law靠堆参数、堆数据的预训练方案现阶段很难再让大模型取得预想的性能提升。
所以像o1这样reasoning模型的做法是通过引入思维链技术,增加模型在test-time阶段的计算,扩展模型推理能力,从而提高性能。
Kimi k1.5 的核心是利用强化学习(RL)训练大模型,并结合长文本处理和策略优化等方法,提升模型的推理能力。
如果按照前期数据准备,到模型设计和训练,再到后期优化和部署这个顺序来看,论文中提到k1.5所采用的创新方法和核心技术包括:
1、数据部分:RL指令集策展
设计了一个高质量的提示集来提高模型的学习效果。
高质量的 RL 提示集具备三个关键属性:多样化的覆盖范围(涵盖多个学科)、均衡的难度(应包含易、中、难各种难度级别的问题)以及准确的可评估性(允许验证器进行客观可靠的评估)。

2、模型设计和训练部分
- 长上下文扩展
- 改进的策略优化
- 简洁的RL框架(Infra)
- 多模态训练
3、优化和部署部分
- long2short方法
- 混合部署训练和推理
上面提到这些,其中RL指令集策展、多模态训练和混合部署训练和推理在我看来属于比较常规的做法,而长上下文扩展、改进的策略优化、RL框架、以及long2short方法则是让k1.5性能得以大幅提升的关键。
下面详细说说关键部分。
核心技术:部分展开(partial rollouts)
在传统的 RL 训练中,对于长文本序列,模型通常需要一次性生成整个轨迹(例如,完整的 CoT 推理过程)。这直接导致计算开销大、内存占用高、训练不稳定,以及数据效率低这些问题。
kimi团队在扩展上下文长度的情况下,采用了一个关键的提高训练效率的技术——partial rollouts。它的核心思想是将长轨迹的生成过程分割成多个迭代步骤,避免一次性生成整个轨迹,从而提高训练效率并节省计算资源。

参考上面这张图。
Partial rollouts 的工作方式是:
(1)固定输出 token 预算。定义一个固定输出 token 数量,作为每次 rollouts 的长度上限(例如,每次生成 500 个 token)。
(2)分段生成。在每次训练迭代中,模型并不生成完整的轨迹,而是只生成部分轨迹,即在 token 数量达到预算上限时停止。
(3)保存中间状态。将生成的中间轨迹片段及其对应的模型状态保存到 replay buffer 中。
(4)多次迭代完成长轨迹。在后续的训练迭代中,模型可以从 replay buffer 中读取之前保存的中间轨迹片段,并在此基础上继续生成新的轨迹片段。通过多次迭代,最终完成整个轨迹的生成。
(5)选择性计算 loss。在计算 loss 时,可以选择只计算当前迭代生成的部分轨迹片段的 损失,也可以计算整个轨迹的 loss,具体策略取决于实际情况。
这个方式显著提升了长上下文任务的处理能力,优化了计算资源,系统能够生成更长的响应,还在不牺牲输出质量的前提下加速了模型训练过程。
我一直觉得在长上下文这块,月之暗面肯定是有点东西的,早期作为最早支持200M长文本/RAG的那批模型,kimi就实现了很好的效果。现在月之暗面又把长上下文优势延续到了推理模型上。
改进的策略优化(Policy Optimization)
讲道理这部分有点复杂,我也没有看得特别明白,可能需要RL大佬做更深入的解读。

简要来说就是k1.5采用一种在线镜像下降的变体进行稳健的策略优化,来训练模型生成长链思维(CoT),并通过正则化技术来避免模型的推理过程偏离目标。通过设计合适的奖励机制和梯度计算方法,模型能够逐步优化推理路径,解决复杂的推理问题。
这个算法通过长度惩罚、有效的采样策略和训练数据的优化等手段得到进一步改进。
long2short方法
尽管long-COT能取得更好的性能,但是超长的思维链也意味着更低的效率,这对于一个要给用户用的模型来说,某些场景下可能是不理想的。Kimi团队发现通过将long-CoT模型中的思维先验转移到short-CoT模型中,也能让它在消耗更少 token 的情况下,获得接近long- CoT 模型的性能。
为了把long-COT模型的思维先验转移到short-COT模型,文章提到了几种long2short方法。
1、模型合并(Model Merging)。直接将long-COT模型和short-COT模型的权重平均,获得一个新的模型,不需要额外的训练。这个方法简化了长链思维模型的泛化过程,同时保留了其强大的推理能力。
2、最短拒绝采样(Shortest Rejection Sampling)。也就是通过long-COT生成多个回答(如每次生成8个),选择最短且正确的作为训练样本对short-COT模型进行监督微调。
3、DPO。DPO类似于最短拒绝采样,但是它把最短且正确的答案被选为正样本,而长度较长的答案被视为负样本(包括错误答案和正确答案,但长度是正样本的1.5倍)。这些正负样本一起用于DPO训练。
4、Long2short RL。在标准RL训练阶段后,kimi团队把性能和token效率最平衡的模型作为基础模型,然后进行long2short RL训练阶段。这个阶段会应用到前面提到的长度惩罚(Length Penalty),以减少CoT展开长度,从而减少推理过程中不必要的长回答和冗长的推理步骤。
在后续的实验中,评估结果表明long2short RL算法在改进short-CoT模型(下图中的k1.5-short w/ rl)时,不仅能提高token效率,而且在多个任务上比其他方法表现更好。比如下图中在MATH500上的结果可以看出,相比于k1.5-long,k1.5-short w/ rl在消耗更少的tokens数量(约1200 vs 1350)的情况下,精度反而更高了,说明long2short RL算法可以在不降低性能的情况下,让short-COT模型效率更高。其他结果也表明算法提升了模型在推理任务中的表现,尤其是在需要精确控制计算资源和token使用的场景下,表现更加突出。
比如k1.5-short w/ rl模型,在AIME2024测试集上,经过8次实验平均消耗3272 tokens的情况下取得了60.8的成绩(Pass@1)。

除了这些模型设计和训练方面的细节,报告里面也介绍了混合部署,以及代码沙盒等方面的实施细节。

不知道是不是被CloseAI影响的,现在看到大模型公司还能发布这么详细的技术报告,第一感觉是真不容易。
粗略的看完,一个感受是虽然已经写得很详细,但是我觉得月之暗面应该还是藏了一些东西的。因为从写出来的这些东西来看,能拿到promising的结果是可以预见的,但是达到这么好的表现——在几个benchmark追平o1,还是有些让人意外。
推理模型在接下来很长一段时间都会是一个非常重要的研究方向,甚至可能是短期内大模型继续走下去的唯一方向。
至于原因,高情商说是充分发挥大模型的“思维”能力,低情商其实就是高质量数据用完了,scaling law暂时走不下去,不得不转换思路。
不过,看到k1.5,以及隔壁的ds R1,这些推理模型相继取得了很好的成绩,我愿意相信未来被赋予“思维”的大模型之后会有更广阔的前途。

期待能早点在web和手机端用上,试试实际效果。
着急的现在可以通过API调用,需要先在这里填个申请。
申请地址:https://docs.google.com/forms/d/e/1FAIpQLScVesbaAtY3RzK8c7O2iCA0EBVFDHXdMfkh_6axjJ9Tb4TEfA/viewform调用方式示例:
# 参考:https://github.com/MoonshotAI/Kimi-k1.5
from openai import Client
client = Client(
api_key="YOUR_KIMI_KEY",
base_url="https://api.moonshot.ai/v1",
)
messages = [
{
"role": "user",
"content": "The lengths of the two legs of a right triangle are 3 cm and 4 cm respectively. Find the length of the hypotenuse of this right triangle.",
},
]
stream = client.chat.completions.create(
model="kimi-k1.5-preview",
messages=messages,
temperature=0.3,
stream=True,
max_tokens=8192,
)
for chunk in stream:
if chunk.choices[0].delta:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
