Files
llm-atlas/research/K3_ARTIFACT_AUDIT.md
T
2026-07-29 12:49:28 +08:00

379 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kimi K3 第三轮:开放工件、权重元数据与可复现实验审计
> 研究截点:2026-07-29
> 官方模型修订:`moonshotai/Kimi-K3@9f62e4e9fffbd0a83ddd60e1c209d828994b3569`
> 官方 FlashKDA 修订:`MoonshotAI/FlashKDA@1ce47ea3bb22c84eb9cc665028399cf35e8ffb0b`
> 原则:模型卡、配置、远程代码、safetensors header、kernel API、作者 benchmark 和本机实验分开记账。
## 1. 本轮究竟要推进什么
第二轮已经把 47 页报告拆成问题、公式、图表和教学实验。第三轮不能只是再写一遍报告,而要回答:
1. 开放权重仓库实际包含哪些文件、分片和张量?
2. 报告的 `69 KDA + 24 MLA`、`1 dense + 92 MoE` 是否能在配置和 tensor names 中闭合?
3. Stable LatentMoE 与 MXFP4 在真实 checkpoint 中怎样落成 packed tensors 与 scales?
4. `NoPE` 在公开实现中究竟是“删掉位置相关通道”,还是“不施加 rotary transform”?
5. AttnRes 在 checkpoint 中留下多少 projection / norm 参数?
6. FlashKDA 的公开接口、支持架构、作者 benchmark 和本机可运行边界分别是什么?
7. 哪些可称为真实工件 trace,哪些仍只是确定性推导或 synthetic probe?
本轮不声称完成以下事情:
- 没有在单张 RTX 5090 上加载 1.56 TB checkpoint;
- 没有获得真实 token hidden states、线上 expert load 或生产 cache trace;
- 没有把随机向量上的 router 行为写成真实数据分布;
- 没有把未成功执行的 FlashKDA kernel 写成“本机 benchmark”;
- 没有替官方解释下面发现的 `A_log` 形状不一致。
## 2. 一手工件与校验
| 工件 | canonical source | 本地校验 |
|---|---|---|
| 模型配置 | `https://huggingface.co/moonshotai/Kimi-K3/blob/main/config.json` | `9710e121…379213` |
| HF configuration code | `configuration_kimi_k3.py` | `735eb9eb…b416ae` |
| 多模态 modeling code | `modeling_kimi_k3.py` | `b9171c96…65ea2` |
| 文本 backbone code | `modeling_kimi_linear.py` | `9e3564c7…ff44a` |
| tensor index | `model.safetensors.index.json` | `a1c52106…7febd` |
| layer-1 KDA 小范围字节 | shard 1 HTTP Range | `dccb10e7…d9b2` |
| layer-2 router prefix | shard 2 HTTP Range | `dbe66ff8…23ee` |
| FlashKDA | `https://github.com/MoonshotAI/FlashKDA` | git `1ce47ea3…f0b` |
完整校验值保存在 `src/data/k3-artifact-snapshot.json`。原始权重字节不进入公开仓库。
### 2.1 为什么只读 Range
模型 tensor data 为 `1,560,860,324,864` bytes,即:
- `1.56086 TB`(十进制);
- `1.41959 TiB`(二进制);
- 96 个 safetensors shards;
- 497,220 个 tensor entries。
当前机器是 32 GB RTX 5090、123 GiB RAM。完整下载和加载既不必要,也不能支持“单卡复现”。
safetensors 把 JSON header 放在每个分片开头;header 给出 tensor name、dtype、shape 与 byte offsets。
因此可以只读:
```text
8-byte header length
→ JSON header
→ selected tensor byte ranges
```
这足以审计结构,也能读取少量参数做统计,同时避免把 1.56 TB 下载行为伪装成研究必要条件。
## 3. checkpoint 拓扑:配置、索引与 header 闭合
### 3.1 层型
配置精确给出:
- 93 层;
- KDA layers:69;
- full-attention / Gated MLA layers:24;
- MLA 位于 1-based `4, 8, …, 92, 93`;
- 第一层 dense,后 92 层为 MoE;
- AttnRes block size 为 12。
因此真实层条带是:
```text
L01 KDA + dense FFN
L02 KDA + MoE
L03 KDA + MoE
L04 MLA + MoE
...
L92 MLA + MoE
L93 MLA + MoE
```
最后连续两个 MLA 不是排版错误:`L92` 是最后一个 3:1 block 的 MLA,`L93` 是报告所述额外末层 MLA。
### 3.2 tensor counts
| 对象 | index 实际计数 | 为什么是这个数 |
|---|---:|---|
| KDA `A_log` | 69 | 每个 KDA layer 一份 |
| KDA `dt_bias` | 69 | 每个 KDA layer 一份 |
| Router weight | 92 | 每个 MoE layer 一份 |
| Router correction bias | 92 | 每个 MoE layer 一份 |
| Routed expert packed weights | 247,296 | `92 × 896 × 3` |
| Routed expert scales | 247,296 | `92 × 896 × 3` |
| AttnRes projections | 187 | `93 × 2 + output 1` |
| AttnRes norms | 187 | `93 × 2 + output 1` |
| Vision tensors | 165 | 27-layer MoonViT-V2 与输入/输出项 |
| Projector tensors | 3 | 视觉塔到 7168 text hidden |
`497,220` 不是“参数数量”,而是 safetensors 中的命名 tensor entry 数。不能和 `2.78T parameters`
混为一个口径。
## 4. 真实 tensor shape:架构不再只靠报告表格
### 4.1 Dense layer 1 的 KDA
shard 1 header 给出:
| tensor | dtype | shape |
|---|---|---|
| `q/k/v/g_proj.weight` | BF16 | `12288 × 7168` |
| `o_proj.weight` | BF16 | `7168 × 12288` |
| `q/k/v_conv1d.weight` | F32 | `12288 × 1 × 4` |
| `b_proj.weight` | BF16 | `96 × 7168` |
| `f_a_proj.weight` | BF16 | `128 × 7168` |
| `f_b_proj.weight` | BF16 | `12288 × 128` |
| dense FFN gate/up | BF16 | `33792 × 7168` |
| dense FFN down | BF16 | `7168 × 33792` |
`12288 = 96 heads × 128 dims`;ShortConv kernel size 4 也直接出现在 checkpoint shape 中。
### 4.2 MLA layer 4
shard 4 header 给出:
| tensor | shape |
|---|---|
| `q_a_proj` | `1536 × 7168` |
| `q_b_proj` | `18432 × 1536` |
| `kv_a_proj_with_mqa` | `576 × 7168` |
| `kv_b_proj` | `24576 × 512` |
| `g_proj` | `12288 × 7168` |
| `o_proj` | `7168 × 12288` |
关键解释:
- `576 = 512 KV latent + 64 auxiliary q/k channel`;
- `q_b` 输出 `96 × (128 + 64) = 18432`;
- 公开 forward 没有对这 64 维施加 RoPE,但仍投影、拼接并进入 attention;
- 因此 K3 的 `mla_use_nope=true` 应解释为“不施加显式 rotary transform”,不能改写成“MLA 中完全不存在任何额外 q/k 通道”。
### 4.3 一个 routed expert 的 MXFP4 表示
layer 2 / expert 0 的 header:
| tensor | dtype | packed shape | bytes |
|---|---|---:|---:|
| `w1.weight_packed` | U8 | `3072 × 1792` | 5,505,024 |
| `w1.weight_scale` | U8 | `3072 × 112` | 344,064 |
| `w2.weight_packed` | U8 | `3584 × 1536` | 5,505,024 |
| `w2.weight_scale` | U8 | `3584 × 96` | 344,064 |
| `w3.weight_packed` | U8 | `3072 × 1792` | 5,505,024 |
| `w3.weight_scale` | U8 | `3072 × 112` | 344,064 |
这里能直接读出两个结构:
1. routed expert 工作在 `3584` latent width,而不是 `7168` full hidden;
2. scale group size 为 32:`3584 / 32 = 112`,`3072 / 32 = 96`。
每个 routed expert 的 packed weights + scales 为 `17,547,264` bytes。按配置与 index 的统一形状推导,
92 层全部 routed experts 约占 tensor data 的 `92.67%`。这是 header + 配置的确定性推导,不是运行显存。
### 4.4 MoonViT-V2
shard 96 header:
| tensor | shape |
|---|---|
| patch projection | `1024 × 3 × 14 × 14` |
| learned 2D position table | `64 × 64 × 1024` |
| block 0 / 26 QKV | `4608 × 1024` |
| block 0 / 26 MLP up | `4096 × 1024` |
| block 0 / 26 MLP down | `1024 × 4096` |
| final norm | `1024` |
配置、首层和末层 tensor 同时支持“27 layers、patch 14、vision hidden 1024”;这比只引用模型卡更强。
## 5. 小参数 Range audit
### 5.1 KDA layer 1
只读 shard 1 开头的 49,664 bytes:
- checkpoint `A_log`: F32 `[128]`;
- `dt_bias`: F32 `[12288]`,可按公开配置写成 `[96, 128]`。
真实参数统计:
| 参数 | median | p10–p90 | min–max |
|---|---:|---:|---:|
| `A_log` | −0.1533 | −0.5367–0.0743 | −0.7531–2.4661 |
| `exp(A_log)` | 0.8579 | 0.5847–1.0771 | 0.4709–11.7764 |
| `dt_bias` | −4.6220 | −6.4912–−2.5690 | −7.8938–0.1792 |
### 5.2 一个必须公开保留的形状不一致
四份官方工件目前给出:
| 工件 | 观测 |
|---|---|
| `config.json` | `num_heads=96`, `head_dim=128` |
| HF remote code | `A_log` 初始化 shape 为 `[num_heads]`,即 `[96]` |
| FlashKDA API / C++ check | `A_log` 必须 `[H]` |
| checkpoint shard header | `A_log` 实际为 `[128]` |
同时:
- `dt_bias` 可闭合为 `[96,128]`;
- `b_proj.weight` 为 `[96,7168]`,β 显然按 96 heads;
- q/k/v projection 为 `12288 = 96×128`。
因此,**公开工件中存在可复现的 `A_log [128]` vs expected `[96]` 形状不一致**。
当前可下的结论只有:
- 这是 header / code / config / kernel API 四方直接观测,不是 Grok 猜测;
- 公开 remote code 按字面构造时会期待 `[96]`;
- 需要 Moonshot、实际 vLLM/SGLang loader 或后续权重修订解释转换规则。
当前不能下的结论:
- 不能直接宣布 checkpoint 损坏;
- 不能擅自把 `[128]` 解释为 per-channel `A_log`;
- 不能用某个猜测 reshape 得到的曲线冒充模型真实 retention。
数据快照保留了一个明确标成 `noncanonical channel-wise hypothesis` 的数值探针,只用于说明:
若把 `[128]` 当 channel 参数,能得到怎样的 retention 分布;它不进入正式 forward 结论。
## 6. Router:真实权重与 synthetic input 必须分层
读取 layer 2 的:
- correction bias:896 个 F32;
- router weight:`896 × 7168` BF16,约 12.85 MB。
真实参数统计:
- correction bias median `0.00493`,min `−0.08442`,max `0.02861`;
- router row L2 median `5.0364`,min `2.6019`,max `7.0232`;
- bias 与 row norm 的 Pearson correlation `0.4567`。
为了测试“只拿真实 router weights 是否就能评价 Quantile Balancing”,脚本生成 2,048 个固定 seed、
RMS=1 的各向同性随机 hidden vectors,再比较 top-16:
| 条件 | load CV | Gini | zero-load experts |
|---|---:|---:|---:|
| 不加 correction bias | 2.085 | 0.831 | 558 |
| 加 checkpoint correction bias | 2.529 | 0.879 | 673 |
两组 top-16 平均只重合 `2.17 / 16`。
这不是在证明 QB 让真实负载更差,反而证明:
1. router weights 与 hidden-state distribution 是共同训练的;
2. sigmoid top scores 在随机 RMS=1 输入下容易饱和;
3. 小 correction bias 会在饱和的近并列区域强烈改写名次;
4. 没有真实 hidden traces,就不能用随机向量评价真实负载均衡。
因此网站把这组结果命名为 **counterexample / synthetic stress probe**,不是“真实 expert load trace”。
## 7. FlashKDA:作者 benchmark 与本机实验分开
### 7.1 官方仓库事实
FlashKDA `1ce47ea3`:
- CUTLASS kernels;
- 支持 `90a / 100a / 103a / 120a`;
- README 要求 SM90+、CUDA 12.9+、PyTorch 2.4+;
- kernel API 固定 `K=V=128`;
- q/k/v/g 为 BF16,`A_log` / `dt_bias` 为 F32;
- 支持 fixed length、variable length、initial / final recurrent state。
官方报告的 `T=8192, H=96, D=128`:
| device | case | FlashKDA | FLA chunk KDA | 作者报告 speedup |
|---|---|---:|---:|---:|
| H20 | fixed | 2.6220 ms | 4.8388 ms | 1.85× |
| H20 | 8×1024 varlen | 2.0432 ms | 4.6723 ms | 2.29× |
| GB200 | fixed | 1.0087 ms | 2.3271 ms | 2.31× |
| GB200 | 8×1024 varlen | 0.7064 ms | 2.3105 ms | 3.27× |
这些是作者仓库 benchmark,不是本站复跑值。
### 7.2 本机真实构建边界
本机:
- RTX 5090,compute capability `12.0`;
- PyTorch `2.11.0+cu128`;
- PyTorch CUDA `12.8`;
- 官方源码明确包含 `sm_120a`,所以不是 GPU architecture 缺失。
两次可复现构建:
1. 系统 `g++ 15.2`:PyTorch extension 在编译前拒绝,CUDA 12.8 要求 host compiler `<14`;
2. 临时解包 `g++ 13.4`:成功进入 nvcc,但 CUDA 12.8 headers 与当前 glibc math declarations
在 `cospi / sinpi / rsqrt` exception specification 处冲突。
结论:
- kernel 尚未在本站机器执行;
- 失败与 README 的 CUDA 12.9+ 要求一致;
- 不能把 `sm_120a` 支持写成本机已经跑通;
- 下一次应使用匹配 PyTorch 的 CUDA 12.9+ toolchain 或官方容器后再复跑 correctness + benchmark。
## 8. 可复现实验入口
脚本:
```text
experiments/k3/checkpoint_probe.py
```
提交的数据快照:
```text
src/data/k3-artifact-snapshot.json
```
脚本会:
1. 解析 config、index 与 selected headers;
2. 校验小范围字节长度和 SHA-256;
3. 统计真实 KDA / router 参数;
4. 运行明确标注的 synthetic router counterexample;
5. 解析 FlashKDA 官方 H20 / GB200 benchmark;
6. 输出本机环境与构建边界;
7. 不提交原始权重。
## 9. 网站实现合同
第三轮开放工件实验室必须有四个视图:
1. **Layer map**:93 层真实 config 条带;显示 KDA/MLA、dense/MoE、AttnRes block。
2. **Tensor anatomy**:checkpoint / expert / vision / MLA tensor shape 与数量。
3. **Parameter audit**:真实 Range statistics,并把 `A_log` mismatch 放在主视区。
4. **Reproduction boundary**:官方 benchmark、本站构建失败点、synthetic router counterexample。
每个视图必须显示证据类型:
- `O` = official artifact observation;
- `D` = deterministic derivation;
- `X` = executed local experiment;
- `S` = synthetic stress probe;
- `U` = unresolved inconsistency。
## 10. 下一轮证据闸门
- [x] 官方 config / code / index revision 固定;
- [x] 96 个分片与 497,220 tensor entries 审计;
- [x] KDA / MLA / MoE / AttnRes / Vision tensor shapes 入账;
- [x] selected open-weight ranges 做真实参数统计;
- [x] 发现并限定 `A_log` shape inconsistency;
- [x] FlashKDA RTX 5090 构建尝试留下可复现边界;
- [ ] 使用 CUDA 12.9+ 匹配环境跑 FlashKDA exact correctness;
- [ ] 取得真实 hidden-state / router load trace;
- [ ] 取得可加载的 reduced checkpoint、官方 trace 或多机资源;
- [ ] 对 Figure 3 / 4 / 5 做真实数值重绘;
- [ ] 对 AttnRes 读取分布做真实 token / layer trace。
## 11. 发布与回归证据
- 源提交:`be2b291`;
- 不可变镜像:`docker.k1412.top/wuyang/llm-atlas:20260729T044605Z-be2b291`;
- OCI digest:`sha256:99aa953e419d537bc03127616546d201bc25624498f892088e69cc633bd00cdf`;
- NAS:Compose Manager project `llm-atlas`,`12010 → 8080`,容器 health `healthy`;
- 代理:NPM host `31`,certificate `41`,forward `100.94.16.3:12010`;
- 公网:DNS `93.179.98.23`,HTTP → HTTPS 301,`/healthz` 与关键静态资源 200;
- 门户:`LLM ATLAS` / `projects` / order `180`;
- 回归:16 套生产 Chrome 脚本全部通过,包含 K3 四视图、键盘 tabs、桌面和 390px 移动端;
- 回滚镜像:`20260729T040336Z-b669615`。