timeline
title Kimi 模型演进路线
2023 Q3 : Moonshot V1 : Dense 模型 : 8K/32K/128K 上下文
2025 Q3 : Kimi K2 : 1T MoE 开源 : MLA + MuonClip : 128K 上下文
2025-09 : Kimi K2.5 : 多模态开源 SoTA : 视觉+文本 : 256K 上下文
2025-10 : Kimi K2.6 : 通用模型 : 思考/非思考模式 : 256K 上下文
2025-10 : Kimi K2.7 Code : 专用编码 : 高速模式 : 256K 上下文
2025-11 : Kimi K3 : 旗舰模型 : 2.8T 参数 : 1M 上下文 : 原生视觉 : 编程 Agent 优化
30 Kimi 系列训推实战
2025 年 7 月,月之暗面(Moonshot AI)开源了 Kimi K2——一个 1 万亿参数的 MoE 模型。这不是又一个”刷榜模型”:它用全新的 MuonClip 优化器在 1T 参数规模上实现了零训练不稳定,用 15.5T tokens 的数据把 Agent 能力推到了开源模型的前沿。更关键的是,K2 的架构直接复用了 DeepSeek-V3 的 MLA + MoE 范式,并在其之上做出了实质性的工程突破。如果说 DeepSeek-V3 证明了”便宜也能训好”,Kimi K2 则证明了”规模可以再上一个台阶”。
30.1 章节导入
30.1.1 从 Moonshot V1 到 K3:一条清晰的演进路线
Kimi 的母公司月之暗面成立于 2023 年,创始人杨植麟是 Transformer-XL 和 XLNet 的核心作者。公司的技术演进路线非常清晰:
这条路线体现了几个关键战略选择:
- 从 Dense 到 MoE:V1 是传统稠密模型,K2 开始全面转向 MoE 架构
- 从闭源到开源:K2 是首个大规模开源的 Kimi 模型
- 从通用到专用:K2.7 Code 专注编程,K3 专注编程 Agent 场景
- 上下文持续扩展:8K → 128K → 256K → 1M
30.1.2 核心技术定位
Kimi K2 的技术定位可以用三个关键词概括:
- MoE(Mixture-of-Experts):1T 总参数,32B 激活参数,384 个专家
- MLA(Multi-head Latent Attention):复用 DeepSeek-V3 的 Attention 机制,大幅压缩 KV Cache
- MuonClip 优化器:Muon 优化器的改进版本,在 1T 参数规模上实现了零训练不稳定
30.1.3 与 DeepSeek-V3 的关系
K2 的架构并非从零设计,而是直接复用了 DeepSeek-V3 的 DeepSeekV3CausalLM 架构(model_type 设为 "kimi_k2")。这意味着:
- Attention 层完全相同:都使用 MLA 机制
- MoE 结构相似但有差异:K2 有 384 个专家(V3 为 256 个),激活 8 个(V3 为 8 个)
- 词表更大:K2 使用 160K 词表(V3 为 129K)
- 优化器不同:K2 用 MuonClip,V3 用 AdamW
graph LR
subgraph "DeepSeek-V3"
D1["MLA Attention"] --> D2["MoE: 256 experts<br/>8 activated + 1 shared"]
D2 --> D3["AdamW"]
D3 --> D4["FP8 Training"]
end
subgraph "Kimi K2"
K1["MLA Attention<br/>(same)"] --> K2["MoE: 384 experts<br/>8 activated + 1 shared"]
K2 --> K3["MuonClip<br/>(new!)"]
K3 --> K4["Block-FP8 Weights"]
end
D1 -.->|"架构复用"| K1
为什么复用 DeepSeek-V3 架构? 这不是”偷懒”,而是工程智慧的体现。MLA + 细粒度 MoE 的范式已经由 DeepSeek-V3 验证了有效性。K2 团队把精力集中在了真正需要突破的地方——优化器和训练稳定性——而不是重复造轮子。这也是开源生态的价值:优秀的设计会被复用和改进。
30.2 Kimi K2 架构深度解析
30.2.1 整体架构概览
先看 K2 的完整架构参数:
| 参数 | Kimi K2 | DeepSeek-V3 | 对比 |
|---|---|---|---|
| 总参数 | 1T | 671B | K2 大 49% |
| 激活参数 | 32B | 37B | K2 更精简 |
| 层数 | 61 | 61 | 相同 |
| Dense 层数 | 1 | 1 | 相同 |
| Attention Hidden Dim | 7168 | 7168 | 相同 |
| MoE Hidden Dim (per expert) | 2048 | 2048 | 相同 |
| Attention Heads | 64 | 64 | 相同 |
| 专家总数 | 384 | 256 | K2 多 50% |
| 每 Token 激活专家 | 8 | 8 | 相同 |
| 共享专家 | 1 | 1 | 相同 |
| 词表大小 | 160K | 129K | K2 大 24% |
| 上下文长度 | 128K | 128K | 相同 |
| Attention 机制 | MLA | MLA | 相同 |
| 优化器 | MuonClip | AdamW | 关键差异 |
| 训练数据 | 15.5T tokens | 14.8T tokens | K2 多 5% |
一个有趣的事实:K2 的总参数比 V3 大 49%,但激活参数反而少 5B(32B vs 37B)。这意味着 K2 的”参数效率”更高——用更少的计算获得更大的模型容量。
30.2.2 MoE 架构设计
30.2.2.1 384 个专家的路由策略
K2 的 MoE 层包含 384 个专家,每个 token 选择 8 个激活,外加 1 个始终激活的共享专家:
graph TD
subgraph "Kimi K2 MoE Layer"
A["Input Hidden State<br/>dim=7168"] --> B["Router / Gate"]
B --> C["Top-8 Selection<br/>从 384 个专家中选 8 个"]
B --> D["Shared Expert<br/>(always active)"]
C --> E1["Expert 1<br/>dim: 7168→2048→7168"]
C --> E2["Expert 2<br/>dim: 7168→2048→7168"]
C --> E3["..."]
C --> E8["Expert 8<br/>dim: 7168→2048→7168"]
E1 --> F["Weighted Sum<br/>(gate scores)"]
E2 --> F
E8 --> F
D --> F
F --> G["Output Hidden State<br/>dim=7168"]
end
每个专家是一个两层 MLP(使用 SwiGLU 激活函数):
import torch
import torch.nn as nn
import torch.nn.functional as F
class Expert(nn.Module):
"""Kimi K2 中的单个 MoE 专家"""
def __init__(self, hidden_dim=7168, expert_dim=2048):
super().__init__()
self.w1 = nn.Linear(hidden_dim, expert_dim, bias=False) # gate
self.w2 = nn.Linear(expert_dim, hidden_dim, bias=False) # down
self.w3 = nn.Linear(hidden_dim, expert_dim, bias=False) # up
def forward(self, x):
# SwiGLU: (x @ w1) * SiLU(x @ w3) @ w2
return self.w2(F.silu(self.w1(x)) * self.w3(x))
class MoERouter(nn.Module):
"""Top-K 路由器"""
def __init__(self, hidden_dim=7168, num_experts=384, top_k=8):
super().__init__()
self.gate = nn.Linear(hidden_dim, num_experts, bias=False)
self.top_k = top_k
def forward(self, x):
# x: [batch * seq_len, hidden_dim]
logits = self.gate(x) # [N, 384]
scores = F.softmax(logits, dim=-1) # [N, 384]
# Top-K 选择
topk_scores, topk_indices = torch.topk(scores, self.top_k, dim=-1)
# 重归一化
topk_scores = topk_scores / topk_scores.sum(dim=-1, keepdim=True)
return topk_indices, topk_scores30.2.2.2 与 DeepSeek-V3 的 MoE 对比
两者的核心差异在于”粒度”策略:
graph LR
subgraph "DeepSeek-V3 MoE"
D_R["256 experts"] --> D_S["8 selected per token"]
D_S --> D_A["~37B activated params"]
end
subgraph "Kimi K2 MoE"
K_R["384 experts"] --> K_S["8 selected per token"]
K_S --> K_A["~32B activated params"]
end
K2 的策略是”更多专家、更精细选择”——384 个专家提供了更大的模型容量(1T vs 671B),但每个 token 只激活 8 个,因此激活参数反而更少。这意味着:
- 推理速度更快:32B 激活 < 37B 激活
- 模型容量更大:1T > 671B
- 专家利用率更低:每次只用到 384 个中的 8 个(2.1%)
30.2.2.3 负载均衡
384 个专家的负载均衡是一个更大的挑战。K2 在训练时使用了辅助损失(auxiliary loss)来确保所有专家被均匀使用:
def load_balancing_loss(affinities, expert_indices, num_experts=384, top_k=8):
"""
affinities: [N, num_experts] - router 的 softmax 输出
expert_indices: [N, top_k] - 被选中的专家索引
"""
N = affinities.shape[0]
# 每个专家被选中的概率
expert_mask = F.one_hot(expert_indices, num_experts).float() # [N, top_k, num_experts]
expert_freq = expert_mask.sum(dim=1).mean(dim=0) # [num_experts]
# 每个专家的平均 affinity
expert_prob = affinities.mean(dim=0) # [num_experts]
# 负载均衡损失
loss = num_experts * (expert_freq * expert_prob).sum()
return loss30.2.3 MLA Attention
K2 完全复用了 DeepSeek-V3 的 MLA(Multi-head Latent Attention)机制。我们在第 27 章已经详细讲解过 MLA,这里只做简要回顾和 K2 特有的参数分析。
30.2.3.1 MLA 核心思想
graph TD
subgraph "标准 MHA"
A1["Hidden State<br/>dim=7168"] --> B1["W_Q → Q (64 heads)<br/>W_K → K (64 heads)<br/>W_V → V (64 heads)"]
B1 --> C1["缓存 K, V<br/>per token: 2×61×64×128"]
end
subgraph "MLA (Kimi K2)"
A2["Hidden State<br/>dim=7168"] --> B2["W_DKV → c_KV<br/>(低秩, dim ≪ 7168)"]
B2 --> C2["只缓存 c_KV!<br/>per token: 61 × latent_dim"]
C2 --> D2["推理时: c_KV → K, V"]
D2 --> E2["Attention 计算"]
end
30.2.3.2 K2 的 KV Cache 计算
对于 K2(61 层,64 头,head_dim=128):
标准 MHA:
KV Cache per token = 2 × 61 × 64 × 128 = 1,001,472 elements
≈ 1.9 MB (FP16)
MLA (假设 latent_dim = 512):
KV Cache per token = 61 × 512 = 31,232 elements
≈ 0.06 MB (FP16)
压缩比: ~32x !
这意味着在 128K 上下文下,K2 的 KV Cache 仅需约 7.9 GB(FP16),而非标准 MHA 的约 250 GB。这使得在有限的 GPU 内存上运行 128K 上下文成为可能。
MLA 的工程价值:对于 1T 参数的模型,如果没有 MLA,128K 上下文的 KV Cache 会消耗数百 GB 内存——即使有 16 张 H200 也难以容纳。MLA 是让 K2 在合理硬件上运行的关键技术。
30.2.4 MuonClip 优化器
MuonClip 是 K2 最核心的技术创新之一。它让 Muon 优化器首次在 1T 参数规模上稳定运行。
30.2.4.1 Muon 优化器原理
Muon(MomentUm + Orthogonalization)是一种结合动量和正交化的优化器。核心思想是对梯度矩阵进行正交化后再更新:
import torch
def muon_update(grad, momentum_buffer, beta=0.95, lr=0.02):
"""
Muon 优化器的单步更新
grad: [m, n] 梯度矩阵
momentum_buffer: 动量缓存
beta: 动量系数
lr: 学习率
"""
# 1. 动量更新
momentum_buffer.mul_(beta).add_(grad, alpha=1 - beta)
# 2. 对动量进行 Newton-Schulz 正交化
# 这将矩阵的奇异值推向 1
momentum_orth = newton_schulz_orthogonalize(momentum_buffer)
# 3. 用正交化后的矩阵更新参数
return -lr * momentum_orth
def newton_schulz_orthogonalize(G, steps=5):
"""
Newton-Schulz 迭代近似正交化
计算 G @ (G^T @ G)^{-1/2}
"""
a, b, c = (3.4445, -4.7750, 2.0315)
X = G.bfloat16()
if G.shape[0] > G.shape[1]:
X = X.T # 保证宽矩阵形式
for _ in range(steps):
A = X @ X.T
B = b * A + c * (A @ A)
X = a * X + B @ X
return X30.2.4.2 为什么 Muon 比 AdamW 更好?
Muon 的优势来自一个数学性质:正交化后的梯度矩阵的所有奇异值都为 1。
| 优化器 | 更新方向 | 步长分配 | 问题 |
|---|---|---|---|
| AdamW | 梯度 / √(二阶矩) | 自适应(按元素) | 大矩阵可能出现”维度坍缩” |
| Muon | 正交化(梯度) | 均匀(按奇异值) | 大规模训练时不稳定 |
| MuonClip | 正交化(梯度) + Clip | 均匀 + 有界 | 稳定! |
AdamW 的问题在于它按元素处理梯度,忽略了矩阵的整体结构。Muon 通过矩阵级别的正交化,确保了更新方向在所有维度上均匀分配。但原始 Muon 在超大规模下会出现训练不稳定——这正是 MuonClip 要解决的。
30.2.4.3 Clip 技术:解决大规模不稳定性
当 Muon 扩展到 1T 参数时,会出现以下问题:
- 梯度范数爆炸:部分层的梯度范数可能突然变得极大
- 正交化数值不稳定:Newton-Schulz 迭代在极端梯度值下可能不收敛
- 训练发散:上述问题叠加后导致 loss 突然飙升
MuonClip 的解决方案是对梯度范数进行裁剪(Clip),在正交化之前确保梯度矩阵的范数在一个合理范围内:
def muonclip_update(grad, momentum_buffer, beta=0.95, lr=0.02,
max_norm=1.0, min_norm=0.1):
"""
MuonClip: 带范数裁剪的 Muon 优化器
"""
# 1. 计算梯度矩阵的 Frobenius 范数
grad_norm = torch.norm(grad, p='fro')
# 2. 范数裁剪(核心创新)
if grad_norm > max_norm:
grad = grad * (max_norm / grad_norm)
elif grad_norm < min_norm:
grad = grad * (min_norm / grad_norm)
# 3. 动量更新
momentum_buffer.mul_(beta).add_(grad, alpha=1 - beta)
# 4. Newton-Schulz 正交化
momentum_orth = newton_schulz_orthogonalize(momentum_buffer)
# 5. 参数更新
return -lr * momentum_orthMuonClip 的意义不仅在于 K2。它证明了一个关键工程事实:Muon 类优化器可以扩展到 1T+ 参数。这意味着未来的超大模型不必再依赖 AdamW——Muon 族的优化器可能成为新的默认选择,带来更快的收敛和更好的最终质量。
30.3 训练系统
30.3.1 大规模预训练
30.3.1.1 训练规模
K2 的预训练规模是空前的:
| 维度 | 数值 | 对比 DeepSeek-V3 |
|---|---|---|
| 训练数据 | 15.5T tokens | 14.8T tokens |
| 模型参数 | 1T | 671B |
| 优化器 | MuonClip | AdamW |
| 精度 | FP8 训练 | FP8 训练 |
| 训练稳定性 | 零不稳定 | 零不稳定 |
15.5T tokens 是什么概念?假设平均一个 token 对应 4 个字节,那训练数据量约为 62 TB 的纯文本。这已经超过了整个英文维基百科(约 25 GB)的 2400 倍。
30.3.1.2 Block-FP8 权重存储
K2 采用了 Block-FP8 格式存储权重,这是对标准 FP8 的重要改进:
graph TD
subgraph "标准 FP8"
A1["权重矩阵 (FP32/BF16)"] --> B1["逐元素量化为 FP8<br/>(E4M3 或 E5M2)"]
B1 --> C1["每个元素 1 字节"]
end
subgraph "Block-FP8"
A2["权重矩阵 (FP32/BF16)"] --> B2["分块<br/>(e.g., 32×32 blocks)"]
B2 --> C2["每块计算独立的 scale"]
C2 --> D2["块内元素量化为 FP8"]
D2 --> E2["每块: 32×32 FP8 + 1 FP32 scale"]
end
Block-FP8 的优势在于每个块有独立的缩放因子,因此对于分布不均匀的权重矩阵,精度损失远小于全局量化的 FP8。
import torch
def block_fp8_quantize(weight, block_size=32):
"""
Block-FP8 量化
weight: [out_features, in_features]
block_size: 块大小
"""
out_features, in_features = weight.shape
# 计算需要多少块
num_blocks_out = (out_features + block_size - 1) // block_size
num_blocks_in = (in_features + block_size - 1) // block_size
quantized_blocks = []
scales = []
for i in range(num_blocks_out):
for j in range(num_blocks_in):
# 提取块
block = weight[
i * block_size : (i + 1) * block_size,
j * block_size : (j + 1) * block_size
]
# 计算块的缩放因子
scale = block.abs().max() / 448.0 # FP8 E4M3 最大值 ≈ 448
# 量化
quantized_block = (block / scale).to(torch.float8_e4m3fn)
quantized_blocks.append(quantized_block)
scales.append(scale)
return quantized_blocks, scales30.3.1.3 训练稳定性保障
1T 参数训练的最大风险是”跑了一半炸了”。K2 声称实现了”零训练不稳定”(zero training instability),这在开源模型中极为罕见。稳定性的保障来自多个层面:
graph TD
subgraph "K2 训练稳定性保障"
S1["MuonClip 优化器<br/>梯度范数裁剪"]
S2["FP8 训练<br/>Block-wise 量化"]
S3["冗余检查点<br/>频繁保存"]
S4["实时监控<br/>梯度/激活/loss 异常检测"]
S1 --> R["零训练不稳定"]
S2 --> R
S3 --> R
S4 --> R
end
30.3.2 后训练(Post-training)
K2 提供了两个版本:K2-Base(基座模型)和 K2-Instruct(指令模型)。从 Base 到 Instruct 的训练流程包括:
graph LR
A["K2-Base<br/>(15.5T tokens 预训练)"] --> B["SFT<br/>监督微调"]
B --> C["Agent 能力训练<br/>工具调用 + 推理"]
C --> D["RLHF / DPO<br/>人类偏好对齐"]
D --> E["K2-Instruct<br/>(开源版本)"]
30.3.2.1 Agent 能力训练
K2-Instruct 的训练重点之一是 Agent 能力——即自主使用工具、推理和解决问题的能力。这解释了 K2 在 Agent 基准上的强劲表现:
| Benchmark | Kimi K2 Instruct | GPT-4.1 | Claude 3.7 | DeepSeek-V3 |
|---|---|---|---|---|
| SWE-bench Verified | 65.8% | 54.6% | 70.3% | 38.8% |
| LiveCodeBench v6 | 53.7% | 44.2% | 56.2% | 46.9% |
| MMLU | 89.5 | 90.2 | 89.2 | 88.5 |
| MATH-500 | 97.4 | 95.6 | 96.2 | 95.8 |
| GPQA-Diamond | 75.1 | 72.0 | 68.2 | 71.1 |
K2 在 SWE-bench 上大幅领先 GPT-4.1(65.8% vs 54.6%),这直接归功于训练数据中大量包含了真实的软件工程任务。
30.3.2.2 Tool Use 优化
K2 的工具调用能力通过专门的训练数据强化。训练流程包括:
- 工具描述理解:学会阅读 API 文档并生成正确的调用格式
- 多轮工具调用:在对话中多次调用不同工具
- 错误恢复:工具调用失败后能自动修正并重试
- 结果整合:将多个工具的返回结果整合成连贯的回答
30.4 推理部署实战
K2 的推理部署是本章的重头戏。1T 参数的模型部署绝非易事,但得益于 MoE 架构(32B 激活)和 MLA(极小 KV Cache),实际部署比看起来可行得多。
30.4.1 硬件需求
首先看硬件门槛:
| 部署方式 | 最小 GPU 数量 | GPU 类型 | 总显存 | 备注 |
|---|---|---|---|---|
| vLLM TP | 16 | H200 (141GB) | 2,256 GB | 最小部署单元 |
| vLLM TP | 16 | H20 (96GB) | 1,536 GB | 国内常见方案 |
| SGLang TP | 16 (2 nodes) | H200/H20 | 2,256 GB | 多节点 |
| KTransformers | 1+ | CPU+GPU 混合 | 灵活 | 成本最低 |
1T 参数的显存需求:即使使用 FP8(每参数 1 字节),模型权重本身就需要约 1 TB 显存。加上 KV Cache、激活值和框架开销,实际需求在 1.2-1.5 TB 之间。这就是为什么最小部署单元需要 16 张 H200(共 2,256 GB)。
30.4.2 vLLM 部署
vLLM 是部署 K2 最直接的方案,需要 v0.10.0rc1 或更高版本。
30.4.2.1 方案一:张量并行(TP ≤ 16)
最简单的部署方式——单节点 16 GPU 张量并行:
# 设置模型路径
export MODEL_PATH="moonshotai/Kimi-K2-Instruct"
# 或本地路径
# export MODEL_PATH="/data/models/Kimi-K2-Instruct"
# 单节点 16 GPU 张量并行
vllm serve $MODEL_PATH \
--port 8000 \
--served-model-name kimi-k2 \
--trust-remote-code \
--tensor-parallel-size 16 \
--enable-auto-tool-choice \
--tool-call-parser kimi_k2 \
--max-model-len 131072 \
--gpu-memory-utilization 0.90 \
--enable-prefix-caching关键参数说明:
| 参数 | 值 | 说明 |
|---|---|---|
--tensor-parallel-size |
16 | 16 路张量并行 |
--trust-remote-code |
- | K2 需要自定义代码 |
--enable-auto-tool-choice |
- | 启用工具调用自动选择 |
--tool-call-parser |
kimi_k2 | 使用 K2 专用工具调用解析器 |
--max-model-len |
131072 | 128K 上下文 |
--gpu-memory-utilization |
0.90 | GPU 显存利用率 |
--enable-prefix-caching |
- | 前缀缓存加速 |
30.4.2.2 方案二:数据并行 + 专家并行(DP + EP)
对于需要更高吞吐量的生产环境,数据并行 + 专家并行是更好的选择:
# ============================================================
# Kimi K2: 数据并行 + 专家并行部署(双节点)
# ============================================================
export MODEL_PATH="moonshotai/Kimi-K2-Instruct"
export MASTER_IP="192.168.1.100" # 主节点 IP
export PORT=29500 # 通信端口
# ---- Node 0 (GPU 0-7) ----
vllm serve $MODEL_PATH \
--port 8000 \
--served-model-name kimi-k2 \
--trust-remote-code \
--data-parallel-size 16 \
--data-parallel-size-local 8 \
--data-parallel-address $MASTER_IP \
--data-parallel-rpc-port $PORT \
--enable-expert-parallel \
--max-num-batched-tokens 8192 \
--max-num-seqs 256 \
--gpu-memory-utilization 0.85 \
--enable-auto-tool-choice \
--tool-call-parser kimi_k2
# ---- Node 1 (GPU 0-7) ----
# 在另一台机器上执行(修改 node-rank)
# vllm serve $MODEL_PATH \
# --port 8000 \
# --served-model-name kimi-k2 \
# --trust-remote-code \
# --data-parallel-size 16 \
# --data-parallel-size-local 8 \
# --data-parallel-address $MASTER_IP \
# --data-parallel-rpc-port $PORT \
# --enable-expert-parallel \
# --max-num-batched-tokens 8192 \
# --max-num-seqs 256 \
# --gpu-memory-utilization 0.85 \
# --enable-auto-tool-choice \
# --tool-call-parser kimi_k2TP vs DP+EP 的对比:
graph TD
subgraph "张量并行 (TP=16)"
TP1["请求"] --> TP2["GPU 0..15<br/>每个 token 都经过<br/>所有 16 个 GPU"]
end
subgraph "数据并行 + 专家并行 (DP=16, EP)"
DP1["请求 Batch"] --> DP2["分发到 16 个 DP rank"]
DP2 --> DP3["每个 rank 独立处理<br/>不同的请求"]
DP3 --> DP4["MoE 层: 专家<br/>分布在不同 GPU"]
end
| 维度 | TP=16 | DP=16 + EP |
|---|---|---|
| 延迟 | 低(单请求并行) | 略高 |
| 吞吐 | 中等 | 高(请求级并行) |
| GPU 通信 | 高(每层都需 AllReduce) | 低(仅 MoE 层通信) |
| 适用场景 | 低延迟、单请求 | 高吞吐、生产环境 |
30.4.2.3 Python 客户端调用
部署完成后,使用 OpenAI 兼容 API 调用:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="dummy" # vLLM 默认不校验
)
# 基础对话
response = client.chat.completions.create(
model="kimi-k2",
messages=[
{"role": "user", "content": "解释一下 MuonClip 优化器的原理"}
],
max_tokens=2048,
temperature=0.7
)
print(response.choices[0].message.content)
# 工具调用
response = client.chat.completions.create(
model="kimi-k2",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"}
],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
}],
max_tokens=512
)
# 解析工具调用
choice = response.choices[0]
if choice.finish_reason == "tool_calls":
for tool_call in choice.message.tool_calls:
print(f"调用工具: {tool_call.function.name}")
print(f"参数: {tool_call.function.arguments}")30.4.3 SGLang 部署
SGLang 是另一个支持 K2 的高性能推理框架。相比 vLLM,SGLang 在大规模生产部署方面有一些独特优势,特别是 PD 分离架构。
30.4.3.1 方案一:张量并行(多节点)
# ============================================================
# Kimi K2: SGLang 张量并行部署(双节点)
# ============================================================
export MODEL_PATH="moonshotai/Kimi-K2-Instruct"
export MASTER_IP="192.168.1.100"
# ---- Node 0 ----
python -m sglang.launch_server \
--model-path $MODEL_PATH \
--tp 16 \
--dist-init-addr $MASTER_IP:50000 \
--nnodes 2 \
--node-rank 0 \
--trust-remote-code \
--tool-call-parser kimi_k2 \
--port 8000
# ---- Node 1 ----
# python -m sglang.launch_server \
# --model-path $MODEL_PATH \
# --tp 16 \
# --dist-init-addr $MASTER_IP:50000 \
# --nnodes 2 \
# --node-rank 1 \
# --trust-remote-code \
# --tool-call-parser kimi_k2 \
# --port 800030.4.3.2 方案二:PD 分离大规模部署
PD 分离(Prefill-Decode Disaggregation)是 SGLang 的杀手级特性,特别适合 K2 这种大规模 MoE 模型的生产部署。
核心思想是将 Prefill(首 token 生成)和 Decode(后续 token 生成)分离到不同的 GPU 集群:
graph LR
subgraph "Prefill 集群 (4 节点)"
P1["32 TP + 32 DP<br/>enable-dp-attention<br/>DeepEP MoE All-to-All"]
end
subgraph "PD Load Balancer"
LB["KV Cache 传输<br/>请求路由"]
end
subgraph "Decode 集群 (12 节点)"
D1["96 TP + 96 DP<br/>low_latency 模式<br/>连续批处理"]
end
P1 -->|"KV Cache"| LB
LB --> D1
4P12D H200 架构详解:
| 集群 | 节点数 | GPU | 并行策略 | 优化模式 |
|---|---|---|---|---|
| Prefill | 4 | 32×H200 | TP=32, DP=32 | DeepEP MoE All-to-All |
| Decode | 12 | 96×H200 | TP=96, DP=96 | low_latency |
为什么 Prefill 和 Decode 要分离?
| 特性 | Prefill | Decode |
|---|---|---|
| 计算密度 | 高(矩阵-矩阵乘) | 低(矩阵-向量乘) |
| Batch 友好度 | 好 | 差(需要 continuous batching) |
| GPU 利用率 | 高 | 低(memory-bound) |
| 最优配置 | 大 batch,高 TP | 小 batch,低延迟 |
PD 分离让每个阶段使用最优的配置,避免了在同一个集群上做取舍。
# ============================================================
# Kimi K2: SGLang PD 分离部署(示例配置)
# ============================================================
# ---- Prefill 节点 (4 节点) ----
python -m sglang.launch_server \
--model-path $MODEL_PATH \
--tp 32 \
--dist-init-addr $MASTER_IP:50000 \
--nnodes 4 \
--node-rank $NODE_RANK \
--trust-remote-code \
--enable-dp-attention \
--enable-deep-ep-moe \
--schedule-conservativeness 0.5 \
--port 8000
# ---- Decode 节点 (12 节点) ----
python -m sglang.launch_server \
--model-path $MODEL_PATH \
--tp 96 \
--dist-init-addr $DECODE_MASTER_IP:50001 \
--nnodes 12 \
--node-rank $NODE_RANK \
--trust-remote-code \
--low-latency \
--schedule-conservativeness 0.3 \
--port 8000PD 分离的适用场景:这种架构专为超大规模生产环境设计(16 节点 = 128 GPU)。如果你只需要在单节点上跑 K2,使用 vLLM 的 TP 方案更简单。PD 分离的优势在于高 QPS 场景——当并发请求量达到数百甚至数千时,它比 TP 方案的吞吐量高出数倍。
30.4.4 KTransformers 部署(CPU + GPU 混合)
KTransformers 是一种创新的部署方案,它将模型的计算分散到 CPU 和 GPU 上——MoE 专家存储在 CPU 内存(DDR)中,Attention 和激活的专家在 GPU 上计算。这使得在有限的 GPU 资源下运行 1T 参数模型成为可能。
graph TD
subgraph "KTransformers 架构"
A["Input Token"] --> B{"Layer Type"}
B -->|"Attention (MLA)"| C["GPU<br/>快速计算"]
B -->|"MoE Expert"| D{"专家选择"}
D -->|"激活的 8 个专家"| E["GPU<br/>加载并计算"]
D -->|"未激活的 376 个专家"| F["CPU DDR<br/>存储(不计算)"]
C --> G["Output"]
E --> G
end
# ============================================================
# Kimi K2: KTransformers 部署
# ============================================================
# 安装 KTransformers
pip install ktransformers
# 下载 GGUF 格式的 K2 模型权重
# huggingface-cli download moonshotai/Kimi-K2-Instruct-GGUF \
# --local-dir /data/models/Kimi-K2-GGUF
# 启动服务
python ktransformers/server/main.py \
--model_path /data/models/Kimi-K2-Instruct \
--gguf_path /data/models/Kimi-K2-GGUF \
--cache_lens 30000 \
--port 8000关键参数:
| 参数 | 说明 | 推荐值 |
|---|---|---|
--cache_lens |
KV Cache 长度 | 30000(根据内存调整) |
--model_path |
原始模型路径(HF 格式) | - |
--gguf_path |
GGUF 量化权重路径 | - |
30.4.4.1 AMX 优化
对于使用 Intel Xeon 处理器的服务器,KTransformers 支持 AMX(Advanced Matrix Extensions)指令集加速 CPU 端的矩阵运算:
# 检查 CPU 是否支持 AMX
lscpu | grep amx
# 如果支持,KTransformers 会自动启用 AMX 优化
# MoE 专家的 FP8 矩阵乘法通过 AMX 加速| 硬件配置 | 推理速度 (tok/s) | 适用场景 |
|---|---|---|
| 1×H100 + 512GB DDR5 + AMX | ~15-20 | 开发测试 |
| 2×H100 + 1TB DDR5 + AMX | ~25-35 | 小规模服务 |
| 8×H100 + 2TB DDR5 | ~50-80 | 中等规模 |
KTransformers 的核心价值:它让没有 16 张 H200 的团队也能运行 K2。代价是推理速度较慢(CPU 内存带宽是瓶颈),但对于开发、测试或低 QPS 场景来说已经足够。配合 AMX 优化,性能可以接受。
30.4.5 TensorRT-LLM 部署
TensorRT-LLM 是 NVIDIA 官方的高性能推理框架,支持 K2 的多节点推理和专家并行。
# ============================================================
# Kimi K2: TensorRT-LLM 部署
# ============================================================
# 需要 TensorRT-LLM v1.0.0-rc2 或更高版本
pip install tensorrt-llm>=1.0.0rc2
# Step 1: 转换模型权重为 TensorRT 引擎
python convert_checkpoint.py \
--model_dir /data/models/Kimi-K2-Instruct \
--output_dir /data/models/K2-engine \
--dtype fp8 \
--world_size 16 \
--tp_size 16 \
--moe_tp_size 16
# Step 2: 多节点启动推理服务
# Node 0
mpirun -np 16 \
--hostfile hostfile \
python run_engine.py \
--engine_dir /data/models/K2-engine \
--port 8000hostfile 示例:
# hostfile
node01 slots=8
node02 slots=8
TensorRT-LLM 支持 EP(专家并行)模式,将 384 个专家分布到不同 GPU 上:
# 使用专家并行
python convert_checkpoint.py \
--model_dir /data/models/Kimi-K2-Instruct \
--output_dir /data/models/K2-engine-ep \
--dtype fp8 \
--world_size 16 \
--tp_size 8 \
--moe_tp_size 2 \
--moe_ep_size 830.4.6 部署方案对比
| 方案 | 最小 GPU | 吞吐 | 延迟 | 易用性 | 适用场景 |
|---|---|---|---|---|---|
| vLLM TP | 16×H200 | ★★★ | ★★★★★ | ★★★★★ | 快速验证、低延迟 |
| vLLM DP+EP | 16×H200 | ★★★★★ | ★★★ | ★★★★ | 生产环境 |
| SGLang TP | 16×H200 | ★★★ | ★★★★ | ★★★★ | 多节点部署 |
| SGLang PD | 128×H200 | ★★★★★ | ★★★★★ | ★★ | 超大规模生产 |
| KTransformers | 1×GPU + CPU | ★ | ★★ | ★★★ | 开发测试、低成本 |
| TensorRT-LLM | 16×H200 | ★★★★ | ★★★★ | ★★★ | NVIDIA 生态深度优化 |
30.5 Agent 能力与工具调用
30.5.1 Tool Calling 最佳实践
K2 是为 Agent 场景特别优化的模型。它的工具调用能力不需要额外的 prompt 工程——只需配置正确的 tool-call-parser。
30.5.1.1 工具调用流程
sequenceDiagram
participant U as 用户
participant M as Kimi K2
participant T as 工具/API
U->>M: "帮我查一下北京的天气"
M->>M: 分析意图,匹配可用工具
M->>T: 调用 get_weather(city="北京")
T-->>M: {"temp": 32, "condition": "晴"}
M->>M: 整合工具返回结果
M-->>U: "北京今天 32°C,晴天。"
30.5.1.2 多工具编排示例
from openai import OpenAI
import json
client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")
# 定义多个工具
tools = [
{
"type": "function",
"function": {
"name": "search_docs",
"description": "搜索技术文档",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "搜索关键词"},
"source": {"type": "string", "enum": ["github", "arxiv", "web"]}
},
"required": ["query"]
}
}
},
{
"type": "function",
"function": {
"name": "write_file",
"description": "写入文件",
"parameters": {
"type": "object",
"properties": {
"path": {"type": "string", "description": "文件路径"},
"content": {"type": "string", "description": "文件内容"}
},
"required": ["path", "content"]
}
}
},
{
"type": "function",
"function": {
"name": "run_command",
"description": "执行 shell 命令",
"parameters": {
"type": "object",
"properties": {
"command": {"type": "string", "description": "要执行的命令"}
},
"required": ["command"]
}
}
}
]
# 模拟工具执行
def execute_tool(name, args):
if name == "search_docs":
return f"找到 3 篇关于 '{args.get('query')}' 的文档..."
elif name == "write_file":
return f"已写入文件: {args.get('path')}"
elif name == "run_command":
return f"命令输出: success"
return "unknown tool"
# 多轮工具调用
messages = [
{"role": "system", "content": "你是一个编程助手,可以搜索文档、写文件和执行命令。"},
{"role": "user", "content": "帮我搜索 MuonClip 优化器的资料,然后整理成一个笔记文件。"}
]
print("=== Kimi K2 Agent 多工具调用演示 ===\n")
for step in range(5): # 最多 5 轮工具调用
response = client.chat.completions.create(
model="kimi-k2",
messages=messages,
tools=tools,
max_tokens=1024
)
msg = response.choices[0].message
if response.choices[0].finish_reason == "tool_calls":
# 模型要调用工具
messages.append(msg.model_dump())
for tool_call in msg.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
print(f"[Step {step+1}] 调用: {func_name}({func_args})")
result = execute_tool(func_name, func_args)
print(f"[Step {step+1}] 结果: {result}")
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
else:
# 模型给出最终回答
print(f"\n[最终回答]\n{msg.content}")
break30.5.2 SWE-bench 实战
SWE-bench Verified 是评估模型自主解决真实 GitHub Issue 能力的基准。K2 在这个基准上取得了 65.8%(单次尝试)的成绩,远超 GPT-4.1(54.6%)。
30.5.2.1 SWE-bench 评测流程
graph TD
A["GitHub Issue"] --> B["K2 分析问题"]
B --> C["定位相关代码文件"]
C --> D["生成修复补丁"]
D --> E{"测试通过?"}
E -->|"是"| F["✅ 解决"]
E -->|"否"| G["分析测试失败"]
G --> D
30.5.2.2 65.8% → 71.6%:多次尝试策略
K2 在多次尝试(best-of-N)下可以达到 71.6%:
# SWE-bench 多次尝试策略
def solve_issue_with_retry(issue, repo_path, max_attempts=5):
"""
使用 Kimi K2 解决 GitHub Issue
多次尝试策略可提升成功率从 65.8% 到 71.6%
"""
attempts = []
for attempt in range(max_attempts):
# 生成候选修复
patch = k2_generate_patch(
issue=issue,
repo_path=repo_path,
previous_failures=attempts, # 让模型看到之前的失败
temperature=0.7 + attempt * 0.1 # 逐步增加随机性
)
# 运行测试
test_result = run_tests(repo_path, patch)
if test_result.passed:
return patch, attempt + 1
attempts.append({
"patch": patch,
"failure": test_result.failure_info
})
return None, max_attempts # 所有尝试均失败30.5.2.3 Agentic Coding 最佳实践
基于 K2 的 Agent 能力,以下是构建 Agentic Coding 系统的最佳实践:
- 提供充分的上下文:K2 能处理 128K 上下文,把完整的项目结构、相关文件和错误日志都给它
- 使用工具链:让 K2 通过工具调用访问文件系统、运行命令、搜索代码
- 多轮迭代:不要期望一次性解决复杂问题——让模型看到测试结果并迭代
- 温度策略:首次尝试用低温度(0.2-0.4)保证确定性,重试时逐步提高
# Agentic Coding 系统示例
class K2CodingAgent:
def __init__(self, vllm_url, repo_path):
self.client = OpenAI(base_url=f"{vllm_url}/v1", api_key="dummy")
self.repo_path = repo_path
self.tools = [
{"type": "function", "function": {
"name": "read_file",
"description": "读取项目中的文件",
"parameters": {
"type": "object",
"properties": {
"path": {"type": "string"}
},
"required": ["path"]
}
}},
{"type": "function", "function": {
"name": "list_files",
"description": "列出目录中的文件",
"parameters": {
"type": "object",
"properties": {
"path": {"type": "string", "default": "."}
}
}
}},
{"type": "function", "function": {
"name": "run_tests",
"description": "运行项目测试",
"parameters": {
"type": "object",
"properties": {
"pattern": {"type": "string", "description": "测试文件模式"}
}
}
}}
]
def solve_issue(self, issue_description):
"""自动解决 GitHub Issue"""
messages = [
{"role": "system", "content": f"""你是一个资深软件工程师。
项目路径: {self.repo_path}
请分析以下 Issue 并生成修复补丁。
Issue:
{issue_description}
请按以下步骤操作:
1. 阅读相关代码
2. 理解问题根因
3. 生成修复补丁
4. 运行测试验证"""},
{"role": "user", "content": "请开始修复。"}
]
for _ in range(20): # 最多 20 轮工具调用
response = self.client.chat.completions.create(
model="kimi-k2",
messages=messages,
tools=self.tools,
max_tokens=2048
)
msg = response.choices[0].message
if response.choices[0].finish_reason != "tool_calls":
return msg.content # 返回最终修复说明
messages.append(msg.model_dump())
for tc in msg.tool_calls or []:
result = self._execute(tc.function.name,
json.loads(tc.function.arguments))
messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})
return "超出最大迭代次数"30.6 Kimi 模型演进路线
K2 只是 Kimi 系列的一个起点。自 K2 开源以来,月之暗面快速迭代了多个版本:
30.6.1 各版本详解
graph LR
K2["Kimi K2<br/>2025-07<br/>1T MoE, 128K"]
K25["Kimi K2.5<br/>多模态 SoTA<br/>视觉+文本, 256K"]
K26["Kimi K2.6<br/>通用模型<br/>思考/非思考, 256K"]
K27["Kimi K2.7 Code<br/>专用编码<br/>高速模式, 256K"]
K3["Kimi K3<br/>旗舰模型<br/>2.8T, 1M 上下文"]
K2 --> K25 --> K26 --> K27 --> K3
| 版本 | 发布时间 | 参数规模 | 上下文 | 核心特性 |
|---|---|---|---|---|
| K2 | 2025-07 | 1T MoE(激活 32B) | 128K | 开源 MoE 基座 + Agent 能力 |
| K2.5 | 2025-09 | - | 256K | 多模态(视觉+文本),开源 SoTA |
| K2.6 | 2025-10 | - | 256K | 思考/非思考双模式 |
| K2.7 Code | 2025-10 | - | 256K | 专用编码模型,高速模式 |
| K3 | 2025-11 | 2.8T MoE(激活 104B) | 1M | KDA 架构 + MXFP4 量化 + 原生视觉 + 编程 Agent 优化 |
30.6.2 K3 架构创新:从 MLA 到 KDA
K3 是 Kimi 系列的最新旗舰模型,2.8T 参数、104B 激活、1M 上下文。但真正让 K3 脱颖而出的不是规模——而是从底层 Attention 机制到训练范式的全面重构。K2 复用了 DeepSeek-V3 的 MLA 架构,K3 则彻底打破了这一路径依赖,用一套全新的技术栈定义了万亿参数模型的新范式。
先看 K3 的完整架构规格:
| 参数 | 值 | 与 K2 对比 |
|---|---|---|
| 总参数 | 2.8T | 2.8× (K2: 1T) |
| 激活参数 | 104B | 3.25× (K2: 32B) |
| 层数 | 93(含 1 层 Dense) | 1.52× (K2: 61) |
| Attention 层组成 | 69 KDA + 24 Gated MLA | 全新 (K2: 全 MLA) |
| Attention Hidden Dim | 7168 | 相同 |
| Attention Heads | 96 | 1.5× (K2: 64) |
| Latent MoE Dim | 3584 | 1.5× (K2: 7168 → 2048/expert) |
| MoE Hidden Dim (per Expert) | 3072 | 1.5× (K2: 2048) |
| 专家总数 | 896 | 2.33× (K2: 384) |
| 每 Token 选择专家 | 16 | 2× (K2: 8) |
| 共享专家 | 2 | 2× (K2: 1) |
| 词表 | 160K | 相同 |
| 上下文长度 | 1,048,576 (1M) | 8× (K2: 128K) |
| Attention 机制 | KDA & Gated MLA | 全新 (K2: MLA) |
| 激活函数 | SiTU-GLU | 新设计 (K2: SwiGLU) |
| 视觉编码器 | MoonViT-V2 (401M) | 新增 (K2: 无) |
| 量化 | MXFP4 权重 / MXFP8 激活 | 原生 QAT (K2: Block-FP8) |
| 模态 | 文本 + 图像 | 多模态 (K2: 纯文本) |
30.6.2.1 Kimi Delta Attention (KDA):取代 MLA 的新架构
K2 和 DeepSeek-V3 使用的 MLA(Multi-head Latent Attention)通过低秩压缩 KV Cache 解决了长上下文的显存瓶颈。但 MLA 在扩展到万亿参数级别时面临两个挑战:一是压缩后的 latent dimension 仍随层数线性增长,二是 prefix caching 的粒度受限于压缩表示。
K3 团队提出了 Kimi Delta Attention (KDA)——一种全新的 Attention 机制,专为超大规模模型设计:
graph TD
subgraph "K2: MLA (全层)"
A1["Hidden State<br/>dim=7168"] --> B1["W_DKV → 低秩压缩<br/>latent_dim ≪ 7168"]
B1 --> C1["缓存 c_KV"]
C1 --> D1["推理时恢复 K, V"]
D1 --> E1["标准 Attention"]
end
subgraph "K3: KDA (69层) + Gated MLA (24层)"
A2["Hidden State<br/>dim=7168"] --> B2["Delta Attention<br/>计算相邻层的增量"]
B2 --> C2["仅缓存 Delta"]
C2 --> D2["选择性检索 + AttnRes"]
D2 --> E2["高效 Attention"]
end
B1 -.->|"K2 路径"| E1
B2 -.->|"K3 新路径"| E2
KDA 的核心思想是增量注意力(Delta Attention):不直接计算完整的 attention matrix,而是计算相邻层之间的注意力增量。这带来三个优势:
- KV Cache 进一步压缩:只存储增量而非完整 KV,缓存大小几乎不随层数增长
- 扩展注意力范围:KDA 天然支持跨层信息检索,不受局部窗口限制
- Prefix Caching 友好:增量表示使得 prefix cache 的粒度更灵活
KDA 对 Prefix Caching 的挑战与贡献
KDA 的增量计算方式改变了 prefix caching 的访问模式——传统的 MLA prefix cache 是按层独立存储的,而 KDA 需要跨层一致性。K3 团队为 vLLM 社区贡献了 KDA 的 prefix caching 实现,使得 KDA 的优势能真正落地到推理引擎中。
30.6.2.2 Attention Residuals (AttnRes):跨深度信息检索
与 KDA 配套的是 Attention Residuals (AttnRes) 机制。传统的残差连接是均匀地将信息从浅层传递到深层:
# 传统残差连接(K2 / DeepSeek-V3)
h = h + attention(layer_norm(h)) # 每层都加一个残差问题在于:并非所有层的信息对所有深度都同等重要。AttnRes 让模型选择性地检索不同深度的表征,而非均匀累积:
# Attention Residuals 概念示意(K3)
def attn_res_forward(self, h, depth_idx):
"""
AttnRes: 不是简单地将当前层输出加到残差流,
而是选择性检索之前各层的表征
"""
# 标准 attention 计算
attn_out = self.attention(self.layer_norm(h))
# AttnRes: 根据深度选择性地融合历史表征
# 浅层(0-30):更依赖局部信息,AttnRes 权重集中在前几层
# 中层(31-60):开始检索更远层的信息
# 深层(61-92):广泛检索全模型的信息
if depth_idx < 30:
# 浅层:标准残差 + 少量跨层
h = h + attn_out
elif depth_idx < 60:
# 中层:选择性检索
h = h + attn_out + self.cross_layer_gate(h, depths=[depth_idx-5, depth_idx-10])
else:
# 深层:广泛检索
h = h + attn_out + self.cross_layer_gate(h, depths=[0, depth_idx//2, depth_idx-3])
return hAttnRes 与 KDA 的组合构成了 K3 的架构骨干——一个为万亿参数以上规模设计的注意力系统。
30.6.2.3 69 KDA + 24 Gated MLA 的混合策略
K3 没有全部使用 KDA,而是采用了 69 层 KDA + 24 层 Gated MLA 的混合架构:
graph LR
subgraph "K3 的 93 层结构"
L0["Layer 0<br/>Dense"] --> L1["Layer 1-23<br/>24× Gated MLA<br/>+ SiTU-GLU MoE"]
L1 --> L2["Layer 24-92<br/>69× KDA<br/>+ AttnRes + SiTU-GLU MoE"]
end
style L0 fill:#e1f5fe
style L1 fill:#fff3e0
style L2 fill:#e8f5e9
为什么是这种混合设计?
- 前 24 层(Gated MLA):浅层需要稳定的、全面的 attention pattern,Gated MLA 提供了经过验证的、稳定的基础表征学习
- 后 69 层(KDA):深层需要更高效的跨层信息检索和更紧凑的 KV Cache,KDA 的优势在这里充分发挥
- Gated MLA 的 Gate 机制:在 MLA 的基础上增加了门控,改善了注意力的选择性——模型可以学会”忽略”不相关的上下文
这种设计是工程务实主义的体现:不在所有地方都用新技术,而是在经过验证的地方保持稳定,在需要突破的地方大胆创新。
30.6.3 Stable LatentMoE:896 专家的稀疏路由
K3 的 MoE 层从 K2 的 384 专家跃升到 896 专家——这是目前开源模型中最大的专家池。但更大的专家池意味着更严峻的路由稳定性挑战。K3 用两项技术创新解决了这个问题。
30.6.3.1 896 专家 / 16 激活的路由设计
graph TD
subgraph "K3 MoE Layer"
A["Input Hidden State<br/>dim=7168"] --> B["Router / Gate"]
B --> C["Top-16 Selection<br/>从 896 个专家中选 16 个"]
B --> D["Shared Expert × 2<br/>(always active)"]
C --> E1["Expert 1<br/>7168→3072→7168"]
C --> E2["Expert 2<br/>7168→3072→7168"]
C --> E3["...×16..."]
C --> E16["Expert 16<br/>7168→3072→7168"]
E1 --> F["加权求和"]
E2 --> F
E16 --> F
D --> F
F --> G["Output Hidden State<br/>dim=7168"]
end
与 K2 的对比:
| 维度 | Kimi K2 | Kimi K3 | 提升 |
|---|---|---|---|
| 专家总数 | 384 | 896 | 2.33× |
| 激活专家 | 8 | 16 | 2× |
| 共享专家 | 1 | 2 | 2× |
| 专家隐藏维度 | 2048 | 3072 | 1.5× |
| 专家利用率 | 2.1% (8/384) | 1.8% (16/896) | 更稀疏 |
| 总参数 | 1T | 2.8T | 2.8× |
| 激活参数 | 32B | 104B | 3.25× |
| 扩展效率 | 基线 | ~2.5× | — |
扩展效率 2.5× 是什么意思?
K3 的总参数是 K2 的 2.8 倍,但激活参数只有 3.25 倍。“扩展效率”指的是:每增加 1 单位激活计算量,获得的模型容量提升。K3 用 3.25× 的计算量获得了 2.8× 的参数——接近线性扩展。这意味着 K3 的架构设计几乎没有”浪费”计算资源。
30.6.3.2 Quantile Balancing:从分位数推导路由
896 个专家的负载均衡是一个前所未有的挑战。K2 使用传统的辅助损失(auxiliary loss)方法来均衡 384 个专家的负载。但当专家数量翻倍以上时,辅助损失方法面临两个严重问题:
- 超参数敏感:辅助损失的权重需要精细调优,在 896 专家规模下几乎无法手动调整
- 启发式更新不稳定:传统的 Expert Choice 路由依赖启发式的 bias 更新,在超大规模下容易震荡
K3 提出了 Quantile Balancing——一种全新的路由均衡方法:
import torch
import torch.nn.functional as F
def quantile_balancing_route(
router_logits, # [N, num_experts] router 输出
num_experts=896,
top_k=16,
target_quantile=0.5 # 目标分位数
):
"""
Quantile Balancing 路由
核心思想:从 router-score 的分位数直接推导专家分配,
而非依赖启发式 bias 更新。
"""
N = router_logits.shape[0]
# Step 1: 计算 router scores
scores = F.softmax(router_logits, dim=-1) # [N, 896]
# Step 2: 计算每个专家的 score 分布的分位数
# 不用均值(容易被极端值拉偏),而用分位数
expert_scores = scores.T # [896, N]
expert_quantiles = torch.quantile(
expert_scores, target_quantile, dim=1
) # [896]
# Step 3: 基于分位数计算平衡 bias
# 目标:让所有专家的分位数 score 尽可能接近
mean_quantile = expert_quantiles.mean()
balance_bias = mean_quantile - expert_quantiles # [896]
# score 偏低的专家获得正 bias,偏高的获得负 bias
# Step 4: 应用 bias 后做 Top-K 选择
adjusted_scores = scores + balance_bias.unsqueeze(0)
topk_scores, topk_indices = torch.topk(
adjusted_scores, top_k, dim=-1
)
# Step 5: 重归一化
topk_scores = topk_scores / topk_scores.sum(dim=-1, keepdim=True)
return topk_indices, topk_scoresQuantile Balancing 的关键优势:
| 特性 | 传统辅助损失 | Quantile Balancing |
|---|---|---|
| 超参数 | 需要调权重(敏感) | 零超参数 |
| 更新方式 | 启发式 bias 更新 | 分位数直接推导 |
| 大规模稳定性 | 896 专家时震荡 | 稳定收敛 |
| 计算开销 | 额外 loss 计算 | 轻量分位数计算 |
Quantile Balancing 的意义超越 K3。随着 MoE 成为大模型的标配,专家数量从 256 → 384 → 896 持续增长,传统的负载均衡方法已经触及天花板。Quantile Balancing 提供了一个无需超参数调优的解决方案,这可能成为未来大规模 MoE 路由的标准方法。
30.6.4 Per-Head Muon 与 SiTU:训练稳定性新范式
将优化器扩展到 2.8T 参数面临的是比 K2(1T)严峻得多的挑战。K3 的训练稳定性由三件套保障:Per-Head Muon、SiTU 激活函数和 Quantile Balancing。
30.6.4.1 Per-Head Muon:独立优化每个注意力头
K2 的 MuonClip 是对整个梯度矩阵做正交化。但当模型扩展到 93 层、96 个注意力头时,不同 head 承担的功能差异巨大——有的 head 关注局部语法,有的 head 跟踪长距离依赖。对它们用同一套优化参数显然不合理。
Per-Head Muon 的核心改进:为每个注意力头维护独立的动量缓冲和正交化参数:
import torch
import torch.nn as nn
class PerHeadMuon:
"""
Per-Head Muon 优化器
为每个注意力头维护独立的优化状态
"""
def __init__(
self,
params,
num_heads=96,
lr=0.02,
beta=0.95,
max_norm=1.0
):
self.num_heads = num_heads
self.lr = lr
self.beta = beta
self.max_norm = max_norm
# 为每个 head 创建独立的动量缓冲
self.momentum_buffers = {}
for name, p in params:
if 'attention' in name and len(p.shape) >= 2:
# 将参数按 head 数量分割
head_dim = p.shape[0] // num_heads
self.momentum_buffers[name] = [
torch.zeros_like(p[i*head_dim:(i+1)*head_dim])
for i in range(num_heads)
]
else:
# 非 attention 参数使用标准 Muon
self.momentum_buffers[name] = torch.zeros_like(p)
def step(self, params_grads):
for (name, p), grad in params_grads:
if name in self.momentum_buffers and isinstance(
self.momentum_buffers[name], list
):
# Per-Head 优化
head_dim = p.shape[0] // self.num_heads
for h in range(self.num_heads):
g_h = grad[h*head_dim:(h+1)*head_dim]
m_h = self.momentum_buffers[name][h]
# 范数裁剪(Clip)
norm = torch.norm(g_h, p='fro')
if norm > self.max_norm:
g_h = g_h * (self.max_norm / norm)
# 动量更新
m_h.mul_(self.beta).add_(g_h, alpha=1 - self.beta)
# Newton-Schulz 正交化
orth = newton_schulz(m_h)
# 参数更新
with torch.no_grad():
p[h*head_dim:(h+1)*head_dim].sub_(self.lr * orth)
else:
# 标准Muon
buf = self.momentum_buffers[name]
buf.mul_(self.beta).add_(grad, alpha=1 - self.beta)
orth = newton_schulz(buf)
with torch.no_grad():
p.sub_(self.lr * orth)
def newton_schulz(G, steps=5):
"""Newton-Schulz 正交化(同 K2)"""
a, b, c = (3.4445, -4.7750, 2.0315)
X = G.bfloat16()
if G.shape[0] > G.shape[1]:
X = X.T
for _ in range(steps):
A = X @ X.T
B = b * A + c * (A @ A)
X = a * X + B @ X
return XPer-Head Muon 的优势在于:不同 head 可以以不同的有效学习率收敛。关注局部语法的 head 可能需要更大的步长,而跟踪长距离依赖的 head 可能需要更精细的更新。这在 2.8T 规模下实现了更自适应的训练。
30.6.4.2 SiTU:新世代激活函数
K2 使用 SwiGLU 作为 MoE 专家的激活函数。K3 提出了 SiTU(Sigmoid Tanh Unit)——一种结合 Sigmoid 和 Tanh 的新型激活函数:
import torch.nn.functional as F
def situ_glufn(x, w_gate, w_up, w_down):
"""
SiTU-GLU 激活函数(K3 MoE 专家使用)
对比 K2 的 SwiGLU:
SwiGLU: (x @ w_gate) * SiLU(x @ w_up) @ w_down
SiTU-GLU: (x @ w_gate) * SiTU(x @ w_up) @ w_down
SiTU(x) = sigmoid(x) * tanh(x)
SiLU(x) = x * sigmoid(x)
"""
gate = x @ w_gate
up = x @ w_up
# SiTU: sigmoid * tanh
activated = torch.sigmoid(up) * torch.tanh(up)
return (gate * activated) @ w_downSiTU 相比 SwiGLU 的优势:
| 特性 | SwiGLU (K2) | SiTU-GLU (K3) |
|---|---|---|
| 有界性 | 无界(x·σ(x)) | 有界(tanh 限制在 [-1,1]) |
| 梯度饱和 | 可能梯度爆炸 | 梯度有界 |
| 激活稀疏性 | 中等 | 更高(负值区域更接近 0) |
| 训练稳定性 | 良好 | 更好(尤其超大规模) |
SiTU 的有界性是关键——在 2.8T 参数的深度网络中,无界激活容易导致中间层激活值爆炸。SiTU 从数学上保证了激活值的范围,为训练稳定性提供了基础保障。
30.6.4.3 三件套协同:2.8T 参数的稳定训练
graph TD
subgraph "K3 训练稳定性三件套"
A["Per-Head Muon<br/>独立优化每个 head<br/>更自适应的学习"]
B["SiTU-GLU<br/>有界激活函数<br/>防止激活爆炸"]
C["Quantile Balancing<br/>零超参数路由均衡<br/>896 专家稳定收敛"]
A --> D["2.8T 参数<br/>零训练不稳定"]
B --> D
C --> D
end
这三个创新分别解决不同层面的稳定性问题: - Per-Head Muon:解决优化层面的稳定性(不同 head 的梯度差异) - SiTU:解决前向传播层面的稳定性(激活值有界) - Quantile Balancing:解决路由层面的稳定性(专家负载均衡)
三者协同,使 K3 在 2.8T 参数规模上实现了与 K2 同等的训练稳定性——这是一个工程奇迹。
30.6.5 MXFP4 原生量化训练
K2 使用 Block-FP8 格式存储权重。K3 更进一步:从 SFT 阶段开始就使用 MXFP4 量化感知训练(QAT),将权重精度压缩到 4-bit——这是目前大规模模型中最激进的量化方案。
30.6.5.1 MXFP4 vs FP8 vs INT4
| 量化方案 | 权重位宽 | 激活精度 | 训练方式 | 硬件兼容性 |
|---|---|---|---|---|
| Block-FP8 (K2) | 8-bit | FP8/BF16 | 后训练量化 | NVIDIA |
| MXFP4 (K3) | 4-bit | MXFP8 | 量化感知训练 (QAT) | NVIDIA + AMD |
| INT4 (常见) | 4-bit | FP16 | 后训练量化 | 有限 |
| GGUF Q4 | 4-bit | - | 推理时量化 | CPU 为主 |
MXFP4(Microscaling FP4)的核心思想是将权重分成小块(通常 32 个元素一组),每组共享一个缩放因子,块内元素仅用 4 bit 表示:
import torch
import struct
def mxfp4_quantize(weight, block_size=32):
"""
MXFP4 量化
weight: [out_features, in_features] FP16/BF16 权重
block_size: 每组的元素数量
MXFP4 格式:
- 每 block_size 个元素共享 1 个 FP8 scale
- 每个元素用 4 bit 存储(FP4: 1 sign + 2 mantissa + 1 exp)
- 压缩比: 16/4 = 4× 相比 FP16
"""
out_features, in_features = weight.shape
weight_flat = weight.reshape(-1)
num_elements = weight_flat.numel()
num_blocks = (num_elements + block_size - 1) // block_size
quantized = []
scales = []
for i in range(num_blocks):
start = i * block_size
end = min(start + block_size, num_elements)
block = weight_flat[start:end]
# 计算块的缩放因子(用 FP8 表示)
max_val = block.abs().max()
# FP4 E2M1 的最大值约为 6.0
scale = (max_val / 6.0).to(torch.float8_e5m2)
# 量化到 FP4
# FP4 E2M1: {0, 0.5, 1, 1.5, 2, 3, 4, 6} × sign
fp4_levels = torch.tensor(
[0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0],
device=block.device
)
normalized = block / scale.to(torch.float32)
# 找到最近的 FP4 level
signs = torch.sign(normalized)
abs_vals = normalized.abs()
indices = torch.argmin(
(abs_vals.unsqueeze(-1) - fp4_levels).abs(), dim=-1
)
quantized_block = signs * fp4_levels[indices]
quantized.append(quantized_block)
scales.append(scale)
return (
torch.cat(quantized).reshape(out_features, in_features),
torch.tensor(scales)
)
# 压缩比计算
# FP16: 16 bit/element
# MXFP4: 4 bit/element + 8 bit/32 elements (scale) = 4.25 bit/element
# 压缩比: 16 / 4.25 ≈ 3.76×
print("MXFP4 权重压缩比: ~3.76× vs FP16")
print("MXFP4 权重压缩比: ~1.88× vs FP8")
# K3: 2.8T params × 4.25 bit ≈ 1.49 TB
# vs FP8: 2.8T × 8 bit = 2.8 TB
# 节省约 48% 的权重存储!30.6.5.2 量化感知训练(QAT)流程
K3 的 MXFP4 不是推理时的事后量化,而是从 SFT 阶段就开始的量化感知训练:
graph LR
A["预训练<br/>BF16 精度"] --> B["SFT 阶段<br/>开始 MXFP4 QAT"]
B --> C["RLHF/DPO<br/>MXFP4 权重 + MXFP8 激活"]
C --> D["最终模型<br/>原生 MXFP4"]
这意味着模型在训练过程中就已经”学会”了在 4-bit 权重下表现良好——相比推理时量化(PTQ),QAT 能显著减少精度损失。
30.6.5.3 硬件兼容性:NVIDIA + AMD
MXFP4 的一个关键优势是广泛的硬件支持:
# ============================================================
# K3 MXFP4 部署:NVIDIA 和 AMD 均支持
# ============================================================
# NVIDIA 方案(vLLM)
docker run --gpus all \
vllm/vllm-openai:kimi-k3 \
--model moonshotai/Kimi-K3 \
--quantization mxfp4 \
--tensor-parallel-size 8
# AMD 方案(vLLM ROCm)
docker run --device /dev/kfd --device /dev/dri \
vllm/vllm-openai_rocm:kimi-k3 \
--model moonshotai/Kimi-K3 \
--quantization mxfp4 \
--tensor-parallel-size 8MXFP4 的战略意义:K3 的 MXFP4 QAT 不只是技术选择——它是一种”硬件民主化”策略。通过确保 AMD GPU 同等支持 K3 的量化格式,月之暗面降低了对 NVIDIA 生态的依赖。这在 GPU 供给紧张的环境下具有重要的商业价值。
30.6.6 K3 部署实战
K3 的部署比 K2 更灵活——虽然模型大了 2.8 倍,但 MXFP4 量化使得实际显存需求大幅降低,且同时支持 NVIDIA 和 AMD 硬件。
30.6.6.1 vLLM 部署(推荐)
vLLM 是部署 K3 的首选方案。K3 需要 vLLM 0.27.0 或更高版本,官方提供了专用的 Docker 镜像:
# ============================================================
# Kimi K3: vLLM 部署(TP8 方案 — 单节点 8×GB300)
# ============================================================
# 方案 1: 张量并行(TP=8),适合低延迟场景
docker run --gpus all --shm-size 16g \
-p 8000:8000 \
-v /data/models:/models \
-e VLLM_USE_V2_MODEL_RUNNER=1 \
-e VLLM_USE_RUST_FRONTEND=1 \
vllm/vllm-openai:kimi-k3 \
--model moonshotai/Kimi-K3 \
--served-model-name kimi-k3 \
--tensor-parallel-size 8 \
--quantization mxfp4 \
--max-model-len 1048576 \
--enable-prefix-caching \
--all2all-backend deepep_v2 \
--moe-backend deep_gemm_mega_moe
# 方案 2: 专家并行 + 张量并行(TEP16),适合多节点
# 需要跨节点的 RDMA 网络
# docker run ... \
# --tensor-parallel-size 16 \
# --expert-parallel-size 16 \
# --all2all-backend deepep_v2 \
# --moe-backend deep_gemm_mega_moe
# 方案 3: PD 分离部署(生产推荐)
# Prefill 和 Decode 分离到不同节点
# 配合 KDA prefix caching 可实现有竞争力的 token 价格关键部署参数详解:
| 参数 | 值 | 说明 |
|---|---|---|
--quantization |
mxfp4 |
使用 MXFP4 量化权重 |
--max-model-len |
1048576 |
1M 上下文 |
--all2all-backend |
deepep_v2 / flashinfer_nvlink_one_sided |
MoE All-to-All 通信后端 |
--moe-backend |
deep_gemm_mega_moe / flashinfer_trtllm |
MoE 计算后端 |
VLLM_USE_V2_MODEL_RUNNER |
1 |
启用 Model Runner v2(性能优化) |
VLLM_USE_RUST_FRONTEND |
1 |
启用 Rust 前端(降低调度开销) |
KDA 对 Prefix Caching 的特殊要求
K3 的 KDA 机制改变了 prefix caching 的访问模式。必须使用 vLLM 社区贡献的 KDA prefix caching 实现(已包含在 vLLM 0.27.0+ 中)。如果你的 vLLM 版本较旧,KDA 层的 prefix caching 可能无法正常工作,导致重复计算。
--all2all-backend 的选择取决于硬件互联:
# RDMA 网络(InfiniBand / RoCE)
--all2all-backend deepep_v2
# NVLink(单节点内 GPU 互联)
--all2all-backend flashinfer_nvlink_one_sided30.6.6.2 SGLang 部署
SGLang 同样支持 K3,包括 NVIDIA 和 AMD 硬件:
# ============================================================
# Kimi K3: SGLang 部署
# ============================================================
# NVIDIA 部署
python -m sglang.launch_server \
--model-path moonshotai/Kimi-K3 \
--tp 8 \
--trust-remote-code \
--quantization mxfp4 \
--port 8000
# AMD 部署(MI355X / MI350X)
# 需要 ROCm 版 SGLang
python -m sglang.launch_server \
--model-path moonshotai/Kimi-K3 \
--tp 8 \
--trust-remote-code \
--quantization mxfp4 \
--port 8000SGLang 还支持 PD 分离部署,架构与 K2 类似(Prefill 集群 + Decode 集群),此处不再赘述。
30.6.6.3 硬件需求
| 部署规模 | GPU 配置 | 适用场景 |
|---|---|---|
| 最小可用 | 8× GB300 (NVIDIA) | 开发测试、低 QPS |
| 生产推荐 | 64+ 加速器超节点 | 生产环境、高 QPS |
| AMD 方案 | 8× MI355X 或 MI350X | AMD 生态部署 |
| 多节点 | 2-4 节点 × 8 GPU | 大规模服务 |
GB300 是什么? GB300 是 NVIDIA Blackwell Ultra 架构的数据中心 GPU,单卡显存 288GB。8× GB300 = 2,304 GB 总显存。K3 的 MXFP4 权重约 1.49 TB,加上 KV Cache 和激活值,8× GB300 刚好够用。
30.6.6.4 API 定价策略
月之暗面为 K3 提供了极具竞争力的 API 定价,核心秘诀是 Mooncake 分离推理架构 的高缓存命中率:
| 计费项 | 价格 | 说明 |
|---|---|---|
| Cache-hit 输入 | $0.30/MTok | 命中缓存的输入 token |
| Cache-miss 输入 | $3.00/MTok | 未命中缓存的输入 token |
| 输出 | $15.00/MTok | 模型生成的 token |
编码工作负载缓存命中率 >90%
在编码场景中,用户请求通常包含大量重复的系统提示、代码上下文和 API 文档。Mooncake 分离推理架构将这些公共前缀缓存在 Prefill 集群中。当缓存命中率 >90% 时,有效输入成本仅为:
$0.30 × 0.9 + $3.00 × 0.1 = $0.57/MTok
这比标准定价低了一个数量级,使 K3 在编码 Agent 场景下的 API 成本极具竞争力。
30.6.6.5 K3 使用特殊注意事项
from openai import OpenAI
client = OpenAI(
base_url="https://api.moonshot.cn/v1",
api_key=MOONSHOT_API_KEY
)
# K3 始终开启 thinking 模式
# reasoning_content 会包含在返回中
response = client.chat.completions.create(
model="kimi-k3",
messages=[
# ⚠️ 多轮对话时,必须将之前的完整 assistant 消息传回!
# 包括 reasoning_content 和 tool_calls
{"role": "user", "content": "分析这段代码的性能瓶颈"},
# 如果有之前的对话,必须原样传回完整的 assistant 消息
# {"role": "assistant", "content": "...",
# "reasoning_content": "...",
# "tool_calls": [...]},
],
# Reasoning Effort: "low" / "high" / "max"(默认 "max")
extra_body={"reasoning_effort": "high"},
# 推荐温度配置
temperature=1.0, # 推荐保持 1.0
top_p=0.95 # 单步任务用 0.95,Agent 任务用 1.0
)
# K3 的返回包含 reasoning_content
choice = response.choices[0]
print("=== 推理过程 ===")
print(choice.message.reasoning_content)
print("\n=== 最终回答 ===")
print(choice.message.content)Preserved Thinking History 模式
K3 始终开启 thinking 模式(reasoning_content 始终返回)。在多轮对话和工具调用中,必须将 API 返回的完整 assistant 消息(包括 reasoning_content 和 tool_calls)原样传回。
如果丢失了 reasoning_content,K3 的后续回答质量会显著下降——因为它依赖之前的推理链来保持上下文一致性。
30.6.7 K3 Benchmark 与能力边界
30.6.7.1 完整 Benchmark 表现
K3 在多个维度与当前最强的闭源模型直接竞争:
| Benchmark | Kimi K3 | Claude Fable 5 | GPT-5.6 Sol | Claude Opus 4.8 | GPT-5.5 |
|---|---|---|---|---|---|
| 编程/Agent | |||||
| DeepSWE | 67.5 | 70.0 | 73.0 | 59.0 | 67.0 |
| Terminal-Bench 2.1 | 88.3 | 88.0 | 88.8 | 84.6 | 83.4 |
| FrontierSWE | 81.2 | 86.6 | 71.3 | 66.7 | 64.9 |
| SWE-Marathon | 42.0 | 35.0 | 39.0 | 40.0 | 14.0 |
| 推理/知识 | |||||
| GPQA Diamond | 93.5 | 92.6 | 94.1 | 91.0 | 93.5 |
| 浏览/检索 | |||||
| BrowseComp | 91.2 | 88.0 | 90.4 | 84.3 | 84.4 |
| OSWorld 2.0 | 58.3 | 66.1 | 62.6 | 55.7 | 49.5 |
| 视觉/多模态 | |||||
| MMMU-Pro | 81.6/83.4 | 81.2/86.5 | 83.0/84.6 | 78.9/82.7 | 81.2/83.2 |
| Video-MME | 90.0 | — | 89.5 | 86.0 | 89.3 |
30.6.7.2 K3 的优势领域
从 Benchmark 数据中可以看出 K3 的几个核心优势:
SWE-Marathon 第一名(42.0):SWE-Marathon 是最困难的软件工程基准——要求模型在长时间跨度(数十轮工具调用)内持续解决问题。K3 以 42.0 大幅领先 Claude Fable 5(35.0)和 GPT-5.6 Sol(39.0),证明了它在持久 Agent 场景下的卓越能力。
FrontierSWE 第二名(81.2):在处理前沿/新颖的软件工程任务时,K3 仅次于 Claude Fable 5(86.6),远超 GPT-5.6 Sol(71.3)。
BrowseComp 第一名(91.2):在网络浏览和信息检索任务中领先所有对手——这对 Agent 场景(需要上网搜索信息)极为重要。
Video-MME 第一名(90.0):在视频理解任务上,K3 原生视觉能力的优势得以体现。
30.6.7.3 K3 的真实世界案例
K3 不只是在 Benchmark 上表现出色——它在真实世界中已经解决了一系列高难度工程问题:
timeline
title K3 真实世界工程案例
GPU Kernel 优化 : 为 NVIDIA GPU 编写优化的 attention kernel : 性能接近手写 CUDA 代码
MiniTriton 编译器 : 构建了基于 Triton 的推理编译器 : 实现了自动 kernel 生成和调优
芯片设计 : 参与了 RISC-V 处理器的微架构设计 : 生成了可综合的 Verilog 代码
这些案例展示了 K3 在 “用 AI 做 AI 基础设施” 这一方向上的潜力——它不仅能写业务代码,还能在系统级编程(GPU kernel、编译器、芯片设计)中提供实质性的工程贡献。
30.6.7.4 K3 的局限性与注意事项
K3 使用中的注意事项
Thinking History 敏感性:多轮对话中如果丢失了
reasoning_content,后续回答质量显著下降。开发者需要确保完整传递 thinking history。过度主动性:K3 在 Agent 模式下有时过于主动——可能会在没有被要求的情况下执行额外操作(如自动运行测试、修改不相关文件)。需要在 system prompt 中明确限制行为边界。
Thinking 始终开启的成本:由于 thinking 始终开启,每个请求都会产生 reasoning tokens 的费用。对于简单任务(如翻译、格式转换),这会造成不必要的成本。可以通过设置
reasoning_effort: "low"来部分缓解。1M 上下文的实际限制:虽然标称 1M 上下文,但在极长上下文(>500K)下,模型的注意力质量会有所下降。建议对超长文档进行分段处理。
30.6.8 从 K2 到 K3:架构演进总结
回顾 K2 到 K3 的完整技术升级路径,可以清晰地看到三条核心进化线索。
30.6.8.1 完整对比表格
| 维度 | Kimi K2 | Kimi K3 | 飞跃 |
|---|---|---|---|
| 规模 | |||
| 总参数 | 1T | 2.8T | 2.8× |
| 激活参数 | 32B | 104B | 3.25× |
| 层数 | 61 | 93 | 1.52× |
| 上下文长度 | 128K | 1M | 8× |
| 架构 | |||
| Attention | MLA | KDA + Gated MLA | 全新 |
| 注意力头 | 64 | 96 | 1.5× |
| 残差机制 | 标准残差 | AttnRes(跨深度检索) | 新设计 |
| MoE | |||
| 专家总数 | 384 | 896 | 2.33× |
| 激活专家 | 8 | 16 | 2× |
| 共享专家 | 1 | 2 | 2× |
| 专家隐藏维度 | 2048 | 3072 | 1.5× |
| 路由均衡 | 辅助损失 | Quantile Balancing | 零超参数 |
| 训练 | |||
| 优化器 | MuonClip | Per-Head Muon | Per-Head |
| 激活函数 | SwiGLU | SiTU-GLU | 新设计 |
| 权重精度 | Block-FP8 | MXFP4(QAT) | 原生 4-bit |
| 激活精度 | FP8/BF16 | MXFP8 | 升级 |
| 多模态 | |||
| 视觉 | 无 | MoonViT-V2 (401M) | 新增 |
| 模态 | 纯文本 | 文本 + 图像 | 多模态 |
| 部署 | |||
| 推理引擎 | vLLM, SGLang, TRT-LLM | vLLM, SGLang | + AMD 支持 |
| AMD 支持 | ❌ | ✅ (MI355X/350X) | 新增 |
| 扩展效率 | 基线 | ~2.5× | — |
30.6.8.2 三大核心飞跃
飞跃一:架构自主创新
K2 是一个”站在 DeepSeek-V3 肩膀上”的模型——复用了 MLA 架构,在优化器上做了突破。K3 则彻底走出了自己的路:KDA、AttnRes、Gated MLA 的混合设计是全新的架构方案。这意味着月之暗面已经具备了从底层 Attention 机制开始设计万亿参数模型的能力。
飞跃二:训练范式的全面升级
从 MuonClip 到 Per-Head Muon,从 SwiGLU 到 SiTU,从辅助损失到 Quantile Balancing——K3 的训练系统是全方位的重新设计。核心目标是:在 2.8T 参数规模上保持与 K2(1T)同等的训练稳定性。这个目标不仅达成了,还通过 MXFP4 QAT 实现了更激进的量化。
飞跃三:硬件生态的民主化
K2 主要面向 NVIDIA 生态。K3 通过 MXFP4 量化(NVIDIA + AMD 均支持)和 vLLM ROCm 镜像,明确将 AMD GPU 纳入一等公民。这在 GPU 供给受限的大背景下具有重要的战略意义。
30.6.8.3 对 AI Infra 工程师的启示
K2 → K3 的演进为 AI 基础设施工程师提供了几个重要洞察:
Attention 机制远未定型:从 MHA → MLA → KDA,Attention 架构仍在快速演进。部署系统需要保持架构可插拔——vLLM 为 KDA 贡献社区实现就是一个很好的例子。
MoE 路由需要新思路:当专家数量超过数百时,传统的辅助损失方法已不够用。Quantile Balancing 的”零超参数”思路值得在自定义 MoE 系统中借鉴。
量化感知训练 > 后训练量化:K3 从 SFT 阶段就使用 MXFP4 QAT,比 K2 的 Block-FP8 后训练量化效果更好。未来的训练系统应该从设计之初就考虑量化。
PD 分离 + 缓存是成本控制的关键:K3 的 API 定价之所以能达到 $0.30/MTok(cache-hit),核心是 Mooncake 架构实现了 >90% 的缓存命中率。这验证了 PD 分离在大规模 MoE 部署中的经济价值。
多硬件支持不再是可选项:K3 同时支持 NVIDIA 和 AMD,这不是”额外工作量”而是核心设计目标。MXFP4 的选择正是基于跨硬件兼容性的考量。
K3 参考资源
- GitHub: https://github.com/MoonshotAI/Kimi-K3
- Tech Blog: https://www.kimi.com/blog/kimi-k3
- Tech Report: https://arxiv.org/abs/2607.24653
- HuggingFace: https://huggingface.co/moonshotai/Kimi-K3
- vLLM Recipe: https://recipes.vllm.ai/moonshotai/Kimi-K3
- SGLang Cookbook: https://docs.sglang.io/cookbook/autoregressive/Moonshotapi/Kimi-K3
- HF Blog (MXFP4): https://huggingface.co/blog/ResterChed/kimi-k3-model-overview-mxfp4-quantization-open-wei
30.6.9 API 平台
除了开源模型,月之暗面还提供了 API 平台,让开发者无需自建推理集群即可使用 Kimi:
import requests
# Kimi API 调用(平台模式)
response = requests.post(
"https://api.moonshot.cn/v1/chat/completions",
headers={
"Authorization": f"Bearer {MOONSHOT_API_KEY}",
"Content-Type": "application/json"
},
json={
"model": "kimi-k2-0711",
"messages": [
{"role": "user", "content": "用 Python 实现一个简单的 HTTP 服务器"}
],
"temperature": 0.7
}
)
result = response.json()
print(result["choices"][0]["message"]["content"])| API 模型 | 上下文 | 特性 | 适用场景 |
|---|---|---|---|
| kimi-k2-0711 | 128K | 基础版本 | 通用对话、编程 |
| kimi-latest | 自动最新 | 始终指向最新版本 | 生产环境 |
| kimi-thinking | - | 思考模式 | 复杂推理 |
30.7 小结
30.7.1 核心要点回顾
本章从架构、训练、部署和 Agent 应用四个维度深入解析了 Kimi K2。三个最值得记住的技术贡献:
MuonClip 优化器:首次将 Muon 类优化器扩展到 1T 参数,零训练不稳定。这不仅是 K2 的成功,更是整个大模型训练方法学的突破——AdamW 可能不再是唯一选择。
大规模 MoE 工程实践:384 个专家、15.5T tokens、Block-FP8 训练——K2 把 MoE 的工程边界推到了新的极限。它证明了 MoE 在 1T+ 参数规模上是可行且高效的。
Agent 优先的模型设计:K2 从训练阶段就注入了 Agent 能力(工具调用、推理、自主问题解决),而不是在后训练阶段临时加上。这使它成为构建 Agentic 应用的理想基座。
30.7.2 与其他开源模型的对比定位
| 维度 | Kimi K2 | DeepSeek-V3 | LLaMA 4 | Qwen 3 |
|---|---|---|---|---|
| 总参数 | 1T | 671B | 400B+ | 235B |
| 激活参数 | 32B | 37B | 17B | 22B |
| 架构 | MoE+MLA | MoE+MLA | MoE+GQA | MoE+GQA |
| 优化器 | MuonClip | AdamW | AdamW | AdamW |
| 上下文 | 128K | 128K | 10M | 128K |
| Agent 能力 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| 中文能力 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 开源协议 | MIT | MIT | LLaMA 4 Community | Apache 2.0 |
何时选择 Kimi K2: 1. 构建 Agent 应用 → K2 的工具调用和推理能力在开源模型中名列前茅 2. 需要 1T+ 参数的大模型容量 → K2 是目前开源的最大 MoE 模型之一 3. 编程/代码场景 → SWE-bench 65.8% 证明了实战能力 4. 中文为主的应用 → 与 DeepSeek 并列的顶级中文能力 5. 追求推理效率 → 32B 激活比 DeepSeek-V3(37B)更精简
部署的硬件门槛:K2 的最小部署单元是 16 张 H200/H20。如果你的硬件资源有限: - 考虑使用 KTransformers(CPU+GPU 混合) - 考虑使用 Kimi API 平台(无需自建集群) - 考虑较小的开源模型(DeepSeek-V3 8×GPU,Qwen 3 4×GPU)
30.8 延伸阅读
- Moonshot AI (2025). Kimi K2 Technical Report. arXiv:2507.20534 — 官方技术报告,必读
- Moonshot AI (2025). Kimi K2 Tech Blog. https://moonshotai.github.io/Kimi-K2/ — 包含可视化图表和交互式 demo
- GitHub: https://github.com/MoonshotAI/Kimi-K2 — 模型代码和部署脚本
- HuggingFace: https://huggingface.co/moonshotai/Kimi-K2-Instruct — 模型权重
- Jordan et al. (2024). Muon: An optimizer for neural networks. Muon 优化器原始论文
- DeepSeek-AI (2024). DeepSeek-V3 Technical Report. arXiv:2412.19437 — K2 架构的基础
- Liu et al. (2024). FP8 Quantization for Deep Learning. Block-FP8 理论基础
- SWE-bench: https://www.swebench.com/ — Agent 编程能力评测基准
- vLLM Documentation: https://docs.vllm.ai/ — K2 部署框架文档
- SGLang Documentation: https://github.com/sgl-project/sglang — PD 分离架构文档
- KTransformers: https://github.com/kvcache-ai/ktransformers — CPU+GPU 混合推理框架