File size: 31,379 Bytes
e9433fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f22b5e
 
e9433fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f22b5e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e9433fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f22b5e
e9433fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f22b5e
 
e9433fd
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
# CMF v2 — 格式规范

*语言:[English](SPEC.md) · [Русский](SPEC.ru.md) · **中文***

**Cortiq Model Format** — 一个文件即可承载稀疏、任务路由推理所需的一切:
量化权重、分词器、逐任务掩码、预计算的稀疏索引 —— 以及独一无二的、
共享同一骨干的**技能集群**(Patent 15)。

> 规范来源:本文档。参考实现:Rust 读取器/运行时
> (`crates/cortiq-core`、`crates/cortiq-engine`)、Python 写入器
> (`converter/`),以及一个无依赖的 Python 读取器
> (`python/cmf_reader.py`,仅需 numpy)。

三项要求,按优先级排序:

1. **正确。** 没有静默损坏模式:严格的魔数、版本、
   `required_features`、每个区段的边界检查、每个张量的 64 位哈希。
   文件要么有效,要么 open() 返回错误 —— 不存在
   第三种状态。
2. **快速。** 权重区段按页对齐以便 mmap,每个张量
   都按 64 字节对齐(零拷贝 SIMD),张量目录为二进制格式 ——
   无需解析即可读取。冷(被掩掉的)权重不占用 RSS。
3. **紧凑。** 掩码按位打包(每个神经元 1 比特),权重采用
   q4/q8/可变位宽,整个文件由一个 128 字节的
   信封寻址。

和谐并非来自特性数量,而是来自**单一正典**:每个层级只有一种
布局(信封、目录、量化块、掩码),在各自领域重叠之处
(张量目录、量化布局、`hash64`)与经过验证的 `.vmfc` v2 格式逐字节
兼容。永远不存在同一事物的两种
定义。

物理基础(VMF):模型是一个真空凝聚态 𝒲;技能是它在临界密度之上的
规则核;任务掩码在不改变权重的情况下选取一个活跃
子集。格式承载了该物理的推论(双场 𝒲×θ 量化、Born 重要性、临界掩码
阈值)—— 但**仅限那些经测量确认的部分**。

---

## 1. 信封(固定 128 字节)

所有整数均为小端序。

```
[0x00 : 0x04]  magic              = b"CMF\x01"  (4 bytes)
[0x04 : 0x08]  version            : u32 = 2
[0x08 : 0x0C]  flags              : u32 (reserved, 0)
[0x0C : 0x10]  required_features  : u32 (bitmask, §1.1)
[0x10 : 0x18]  header_off         : u64 (= 128)
[0x18 : 0x20]  header_len         : u64   — JSON header (§2)
[0x20 : 0x28]  dir_off            : u64   — tensor directory (§3)
[0x28 : 0x30]  dir_len            : u64
[0x30 : 0x38]  data_off           : u64   — weight blob; multiple of 4096 (§4)
[0x38 : 0x40]  data_len           : u64
[0x40 : 0x48]  masks_off          : u64   — masks section (§5); 0 = absent
[0x48 : 0x50]  masks_len          : u64
[0x50 : 0x58]  vocab_off          : u64   — tokenizer (§6); 0 = absent
[0x58 : 0x60]  vocab_len          : u64
[0x60 : 0x68]  index_off          : u64   — sparse index (§7); 0 = absent
[0x68 : 0x70]  index_len          : u64
[0x70 : 0x80]  reserved           : 16 bytes (§8.1: header/dir hashes)
```

磁盘上的区段顺序:信封 → 头部 JSON → 目录 → **权重
blob(对齐到 4096)** → 掩码 → 词表 → 稀疏索引。读取器必须
仅通过信封来寻址区段,绝不假设其顺序。

### 1.1 `required_features`

读取器不认识的某一位 → `UnsupportedFeature` 错误(快速失败;
不做"尽力读取")。

| bit | name           | 含义 |
|-----|----------------|---------|
| 0   | `TENSOR_DIR`   | 二进制张量目录(v2 中始终置位) |
| 1   | `BINARY_MASKS` | 存在掩码区段(§5) |
| 2   | `QUANT_2F`     | 目录包含 `q8_2f`/`vbit` 张量(双场 𝒲×θ 量化) |
| 3   | `DELTA_MASKS`  | 保留:来自父级的 XOR 掩码增量 |
| 4   | `HOT_PACKS`    | 保留:物化的稠密切片 |
| 5   | `LOOP_MASKS`   | 掩码行按访问(VISIT)存储(物理层 × 循环数,按遍历优先)——循环 Transformer 的每一遍携带独立掩码(§5.1) |
| 6   | `SKILL_FILE`   | 该文件是独立技能文件:针对特定基座裁出的部分张量集,由 `SkillRecord.base_dir_hash` 绑定(§9.1)。不可运行——用 `cortiq skill apply` 附加 |

未知的**头部 JSON** 字段被忽略(增量式演进);
破坏性变更只通过特性位或 `version` 递增来引入。

### 1.2 校验规则(规范性)

在以下情况下,读取器必须返回错误(而非默认值、也非警告):

- magic ≠ `CMF\x01``InvalidMagic`- `version` ≠ 2 → `UnsupportedVersion`(v1 已死:不存在真实的 v1
  文件,不会启动任何支持计划);
- 置位了未知的 `required_features` 位 → `UnsupportedFeature`- 任何区段越过 EOF、`data_off` 不是 4096 的倍数、某张量的
  `off + nbytes` 超过 `data_len``Bounds`- 张量名非 UTF-8、dtype 未知、`ndim > 6``Parse`。

张量哈希校验按需进行(`cortiq verify`、加载器标志),
并非每次打开都做:mmap 页面按需惰性读取。

## 2. 头部 JSON

UTF-8 JSON,不对齐。机器关键数据存放于二进制区段;
JSON 承载架构与来源信息 —— 供人阅读的部分。

```jsonc
{
  "format": "cmf",
  "version": 2,
  "arch": {
    "arch_name": "qwen3.5",
    "hidden_size": 5120, "intermediate_size": 17408,
    "num_layers": 64, "num_attention_heads": 24, "num_kv_heads": 4,
    "head_dim": 256, "vocab_size": 248320,
    "layer_types": ["LinearAttention", "...", "FullAttention"],
    "rms_norm_eps": 1e-6,
    "norm_style": "qwen",            // "qwen": x̂·w | "gemma": x̂·(1+w)
    "rope_theta": 1000000.0,
    "tie_word_embeddings": false,
    "max_position_embeddings": 262144,
    "linear_conv_kernel_dim": 4,
    "linear_num_key_heads": 16, "linear_num_value_heads": 48
  },
  "quant_type": "Q4_BLOCK",          // informational default; truth = per-tensor dtype in the directory
  "provenance": { "tool": "…", "source_model": "…" }   // optional, free-form
}
```

`norm_style` 对引擎而言是强制的:把 Gemma 风格的 `(1+w)` 应用到
Qwen 权重上,会在一次前向传播的全部约 130 次归一化中产生静默的垃圾结果。

能力分派由**张量存在与否驱动**:引擎根据目录中存在什么来
逐层决定算子(q/k 偏置、qk 归一化、由投影宽度决定的输出门、MoE 路由器、GDN 投影)
—— 而非通过匹配模型名称。已知家族的新模型可以在
零引擎改动的情况下加载。

### 2.1 MTP —— 多 token 预测(可选)

如果模型携带 MTP 头(DeepSeek/Qwen 风格),arch 声明:

```jsonc
"mtp": { "num_layers": 1, "share_lm_head": true, "share_embed": true }
```

MTP 张量是使用规范名称的普通目录条目
(`model.mtp.*`):`enorm.weight``hnorm.weight``eh_proj.weight [hidden, 2·hidden]``layers.{i}.*`(一个标准的
transformer 块)、`norm.weight`。

语义:`x = eh_proj·[enorm(embed(t_{p+1})); hnorm(h_p)]` —— 嵌入
在先(oracle 验证:反过来的顺序会得到恰好 0% 的接受率)
→ 块 → 共享 lm_head → 对 token `t_{p+2}` 的草稿。读取器无需
执行 MTP(元数据 + 普通张量,增量式
演进,无特性位);CMF 运行时将该头用于
推测解码,并有严格保证:**输出与纯贪婪解码完全相等** ——
被拒绝的草稿会从 KV 中回滚。

### 2.2 MoE —— 专家混合 FFN(可选)

如果模型携带 MoE 层(Qwen2-MoE / Qwen3-MoE / Qwen3.5-MoE),
arch 声明:

```jsonc
"moe": {
  "num_experts": 256, "top_k": 8, "moe_intermediate_size": 512,
  "norm_topk_prob": true,                       // Qwen2-MoE: false
  "shared_expert_intermediate_size": 512        // absent if no shared expert
}
```

张量是使用 HF 名称的普通目录条目:

```
model.layers.{i}.mlp.gate.weight                    [num_experts, hidden]  router
model.layers.{i}.mlp.experts.{e}.{gate,up,down}_proj.weight
model.layers.{i}.mlp.shared_expert.{gate,up,down}_proj.weight
model.layers.{i}.mlp.shared_expert_gate.weight      [1, hidden]
```

哪些层是 MoE,由目录中路由器的**存在与否**决定
(逐层而非逐模型):Qwen2-MoE 的
`mlp_only_layers`/`decoder_sparse_step` 会产生混合模型,稠密
层保留普通的 `mlp.*_proj`。

执行语义(HF 对齐,由 `tests/moe_parity.sh` 在
四个家族上把关,包括融合的 AgentWorld 布局):对全部
路由器 logits 做 softmax → top-k(平局时:取较低索引,torch.topk 顺序)→ 若
`norm_topk_prob`,对所选的 k 个重归一化 → Σwₑ·FFNₑ(x);共享
专家总是以权重 `sigmoid(shared_expert_gate·x)` 加入。
专家在 mmap 中保持量化状态;每个 token 只触及所选
k 个的页面 —— 与技能相同的驻留机制。写入器应当把一层的专家张量按角色
连续排布(专家 0…N−1 的全部 `gate_proj` 相邻,然后全部 `up_proj`,再
全部 `down_proj`)——GPU 后端便可把一层的专家库当作一个区域处理,而
不是收集数百个切片;原生导入器与 `moe-defrag` 都按此顺序写出。每个专家是一个
单独的目录条目,各有**自己的** dtype:这正是
逐专家位宽分配的载体(P15 claim 12)—— 已实现,由
`tests/moe_vbit.sh` 把关;B 场(通过 `--route-stats` 得到的路由器选择频率)
已在一个 35B 模型上端到端测量。

## 3. 张量目录

逐字节采用 `.vmfc` v2 布局(单一正典,共享参考
解析器):

```
[0 : 8 ]  count    : u64
[8 : 16]  pool_off : u64            (name-pool offset from section start)
[16 : 16 + count·56]  56-byte records:
   name_off : u32   (relative to pool_off)
   name_len : u16
   dtype    : u8    (§3.1)
   ndim     : u8    (≤ 6)
   shape    : u32 × 6  (zero-padded tail)
   off      : u64   (RELATIVE to data_off; multiple of 64)
   nbytes   : u64
   hash     : u64   (hash64 of the tensor bytes, §8)
[pool_off : …]  UTF-8 name pool
```

张量名与源模型**一一对应**`model.layers.{i}.mlp.gate_proj.weight``model.embed_tokens.weight``lm_head.weight`、…)。格式不规定张量集合:
目录是 blob 内容的唯一真相来源。
不存在"可计算布局"。

### 3.1 `dtype`

编号与 `.vmfc` 共享(id 从不重用):

| id | name       | 在 CMF v2 中的状态 |
|----|-----------|------------------|
| 0  | `f32`     | ✅ 读/写 |
| 1  | `f16`     | ✅ 读/写(归一化及 1 维张量始终为 f16) |
| 2  | `bf16`    | ✅ 读/写 |
| 3  | `q8_row`  | ✅ 读/写 |
| 4  | `q4_block`| ✅ 读/写 |
| 5  | `mix8_4`  | 保留 |
| 6  | `u8`      | 保留 |
| 7  | `q4_col`  | 保留 |
| 8  | `vbit`    | ✅ 读/写(`QUANT_2F` 位),可变 3–8 位 |
| 9  | `q8_2f`   | ✅ 读/写(`QUANT_2F` 位),𝒲×θ |
| 10 | `vbit_ro` | ✅ 读/写——`vbit` + 文件内行偏移表(O(1) 行访问);`--quant vbit` 的转换器默认 |
| 11 | `q4_tiled`| ✅ 读/写——交错平铺的 q4 `[f16 scale][16B nibbles]``--quant q4t`) |
| 12 | `q1`      | ✅ 读/写——1 位二值权重,仅用于按 1 位训练的模型(`--quant q1`);每 32 组一个 `[f16 scale][4B 符号位]` 平铺,`w = s·(2·bit−1)` |
| 13 | `q1s`     | ✅ 读/写——`q1` 基底 + 稀疏高精度离群值覆盖层(普通检查点的 1 位 PTQ):基底之后是 `[u32 count]``count × { [u32 扁平索引][f16 值] }`;变长,读取器信任目录中记录的字节数 |
| 14 | `q1t`     | ✅ 读/写——三值 `{−s, 0, +s}`(BitNet b1.58 风格):每 32 组 `[f16 scale][7B base-3 码]`(每字节 5 个三值,3⁵=243≤256;码 0→0、1→+s、2→−s,约 2.25 bpw),随后按行的离群值覆盖层 `[u32 row_ptr[rows+1]]` + `{ [u16 col][f16 值] }`(第 r 行的离群值在 `[row_ptr[r], row_ptr[r+1])``col` 为行内索引);变长,规则同 `q1s` |
| 15 | `q4tp`    | ✅ 读/写——`q4_tiled` 的 nibble,但每块 scale 改为按行阶梯上的 5 位档位(`--quant q4tp`,或用 `requant` 就地转换) |

### 3.2 量化布局(正典 = `.vmfc`:"先量化值,后 scale")

- **`q8_row`**(仅限二维 `[out, in]`):
  `[int8 : out·in][f16 : out]` —— 每行一个 scale,
  `w = q[o,i]·scale[o]`,`scale[o] = absmax(row_o)/127`。
- **`q4tp`**(仅限二维,`in % 32 == 0`):
  `[nibbles: rows·gpr·16][行参数: rows × (f16 lo, f16 step)]
   [codes: rows × ceil(gpr·5/8),5 位 LSB-first,按行对齐]`,`gpr = in/32`。
  每块 scale 为 `2^(lo[r] + code·step[r])`,因此读取方只需展开该行的 32 级
  阶梯一次,之后按表查 scale。nibble 的取值与顺序同 `q4_tiled`,仅 scale 的
  表示不同:4.17 bit/weight 对 4.50——f16 scale 曾占 q4t 文件的 11%。
  `lo`/`step` 取自该行 log-scale 的精确 min/max,故码值绝不会越界,格式无需
  逃逸机制。编码器**必须**先把 `lo`/`step` 舍入到 f16 再选码,并按重建后的
  scale 量化 nibble——否则写入方与读取方会不一致(这正是 q4 编码器必须先舍入
  scale 的同一个陷阱)。
- **`q4_block`**:在展平张量上按 32 分组,零填充;
  `[u8 : ceil(n/32)·16][f16 : ceil(n/32)]`。
  半字节:元素 `2k` 为低位,`2k+1` 为高位;`w = (q − 8)·scale``scale = absmax(group)/7`- **一维张量以及元素数 < 32 的张量始终为 `f16`**
  (在矩阵最大压缩下保持归一化精度)。
- **`q8_2f`**:`[int8][f16 row-scale][f16 col-field]`,
  `w = q·scale[o]·col[i]` —— 双场 Madelung 拆分 𝒲×θ,在
  vmfcore 中已验证(同尺寸下 +37%;在离群输入通道上恢复了 q8→f16 差距的约 75%)。
- **`vbit`**(仅限二维,`in % 32 == 0`;P13 FIG.3):
  `[u8 bits: rows][f16 scales: rows·in/32][bit-packed rows, MSB-first,
  each row padded to a byte]`;`w = (u − L)·scale[r,g]`,
  `L = 2^{b−1}−1`,位宽 b ∈ {3,4,5,6,8},下限 3(claim 13)。
  分配 b_r:在 log2 行幅度上朝张量的平均预算做注水;
  对于 MoE 专家,预算在**家族内共享**(层 × 投影):偏移
_expert − ā_family` 等价于在所有专家的行上做联合注水 —— 一个响亮的
  专家获得更多位,一个安静的被钉在下限(P15
  claim 12;gate `tests/moe_vbit.sh`)。分配可选地
  与一个 B 场取积 —— 在标定时收集的路由器选择频率
  (`b ∝ log2(A·B)`,截断 Fisher)。

## 4. 权重 blob

`data_off` 是 4096 的倍数(按页对齐的 mmap);其中每个张量
都从 64 字节边界开始(SIMD 加载、缓存行)。张量之间为零
填充。读取器只能通过目录来解释该 blob。

## 5. 掩码区段

任务掩码 = 在共享权重之上"哪些活跃"的位字段(权重不变
—— VMF 原则:技能选取凝聚态的一个
子集)。

```
[0 : 4]  n_masks  : u32
[4 : 8]  meta_len : u32
[8 : 8 + meta_len]  JSON meta (§5.1)
[…]      mask blobs, each aligned to 8 from the section start
```

一个掩码 blob(尺寸由 arch 推导,无内部头部):

```
[n_layers × ffn_bytes]   FFN bitfields      ffn_bytes  = ceil(intermediate_size / 8)
[n_layers × head_bytes]  head bitfields     head_bytes = ceil(num_attention_heads / 8)
[gates_bytes]            layer_gates        gates_bytes = ceil(num_layers / 8)
[n_layers × expert_bytes] expert bitfields  可选——仅当该掩码的 meta 设置
                                            "has_expert_fields": true;
                                            expert_bytes = ceil(moe.num_experts / 8)
```

位序为 LSB 优先:神经元 `i` = 字节 `i / 8` 的第 `i % 8` 位;置位
→ 活跃。**超出维度的尾部位必须为零**(否则
popcount 会看到幻影神经元/头)。

可选的专家区域(增量式:旧读取器从不读 gates 之后的内容,且每个掩码
的 `blob_len` 是显式的)让任务掩码收窄 MoE **路由**:第 `l` 层行的第
`e` 位置位 → 专家 `e` 对该任务可路由;选择只在可路由集合上进行,
路由器 softmax 在其上重新归一化。这是 §11.1 物理专家碎片整理的运行时
可切换孪生——一个携带完整专家集的文件服务多个专才(`cortiq moe-mask`
写入此类掩码,`run --task <名称>` 激活;已验证与等价的运行时限制逐
词元一致)。整行为 1 的层不受限制;不带该区域的掩码不做任何收窄。

### 5.1 掩码 JSON meta

```jsonc
{
  "default_task": "general",
  "masks": [{
    "task_id": 0, "name": "general", "description": null,
    "sparsity": 0.62,
    "quality": {                    // null = NOT MEASURED (declaring 1.0 is forbidden)
      "metric": "heldout_ppl_ratio", "value": 0.97,
      "baseline_dense": 6.10, "n_samples": 512, "dataset_sha256": "…"
    },
    "parent": null, "priority": "Fallback", "has_hot_pack": false,
    "blob_off": 4096, "blob_len": 139328   // relative to section start
  }]
}
```

`quality` 是一份**留出集契约**,而非一个声明:没有实测指标的
转换器写入 `null`;运行时在切换到未测量掩码时会记录警告。

## 6. 分词器区段

HuggingFace `tokenizer.json` 的字节,逐字保留。模型
自包含:一个文件 = 一个分发单元。附带文件
仍作为调试回退。

### 6.1 聊天捆绑(`header.tokenizer_config`)

是文件 —— 而非运行时二进制 —— 定义了聊天行为。头部
携带一个可选块(增量式演进,无特性位):

```json
"tokenizer_config": {
  "chat_template": "<Jinja template from chat_template.jinja or tokenizer_config.json>",
  "eos_token_ids": [248044, 248045],
  "bos_token_id": null,
  "pad_token_id": 248055
}
```

运行时以 HF 语义渲染模板(trim_blocks、
lstrip_blocks、循环控制、Python 字符串方法),并在
`eos_token_ids` 中的任一 id 处停止生成。Gate:
`tests/chat_template_parity.sh` —— 运行时渲染结果与参考
jinja2 逐字节相等。没有该块的文件获得 ChatML 回退。

## 7. 稀疏索引

一座预计算的"掩码 → 计算跳过"桥梁:逐 (task, layer) 对的
活跃 FFN 量化组(每组 32 个神经元)与头。

> 诚实的状态:引擎直接从掩码位字段取活跃索引;索引会被 CLI 读取并
> 显示,但从未用于执行。**待弃用**:写入器应停止生成它(读取器继续
> 解析既有文件);只有当"掩码 × 量化 mmap"路径以实测收益落地时才会
> 复活。

```
[0 : 4]  n_entries : u32
[4 : 8]  reserved  : u32 (0)
entry (4-aligned):
   task_id   : u32
   layer_idx : u32
   n_groups  : u32
   n_heads   : u32
   [u16 × n_groups]  active FFN-group indices (sorted)
   [u8  × n_heads]   active head indices (sorted)
   zero padding to a multiple of 4
```

一个组只要包含至少一个活跃掩码位即为活跃。

## 8. `hash64`

张量字节的非加密 64 位哈希:在 64 位 LE 字上做 murmur3
`fmix64`,带位置盐 `i·0x9E3779B97F4A7C15`,XOR 折叠、
`xor len`、最终 `fmix64`。与
`vmfcore.hash64`(Python)及 `vmfcore::hash64`(Rust)逐位兼容 ——
`.cmf` 与 `.vmfc` 之间共享张量的哈希相符(跨技能文件的
骨干去重是免费的)。

用途:`cortiq verify`(损坏检测)、去重、缓存键。

### 8.1 区段哈希

元数据完整性(不仅是张量):

- 信封保留区 `[0x70:0x78]` = hash64(header JSON),`[0x78:0x80]` =
  hash64(directory)。零 = "缺失"(旧文件可通过)。
- 头部 JSON 携带 `section_hashes` —— masks/vocab/index 的十六进制
  hash64(u64 若作为 JSON 数字,超过 2^53 会损失
  精度)。信封中的头部哈希传递性地覆盖它们。
- 信封自身(前 0x70 字节)不被哈希:哈希无法
  保护自己;损坏的偏移量会被链条下游的边界/哈希捕获。
- `cortiq verify` 检查整条链;单个被翻转的头部字节
  就是一个错误。

### 8.2 分离式签名(真实性,可选)

哈希链证明完整性,但不证明作者身份。`cortiq sign` 写出分离的
`<model>.sig` —— JSON `{alg: "ed25519-sha256", pubkey, sha256, sig}`,
即对文件 SHA-256 的 Ed25519 签名——容器本身从不被重写,旧工具不受
影响。当 `.sig` 位于模型旁边时,`cortiq verify` 自动校验签名;缺失
不算错误。密钥是签名者私存的 32 字节十六进制种子文件。

## 反特性 —— 格式刻意不具备的东西

- **可计算权重布局** —— v1 的一号 bug 类别(写入器与读取器
  各自"计算"布局并发生分歧)。
- **静默回退** —— v1 会把任何垃圾文件解释为"一个 27B
  模型";v2 必须失败。
- **用 JSON 存位数据** —— v1 掩码用 JSON 存储会膨胀 3–4 倍。
- **声明字段** —— 默认的 `quality_score: 1.0`、面积律
  "容量"、动力学中的 Born 乘子:隐喻在被测量之前
  不会成为格式字段。

## 9. 技能 —— 一个文件中的集群(Patent 15,claims 2/12/15)

一个共享骨干 + K 条逐技能记录;没有任何记录存储完整
模型。存储量按 |backbone| + Σ|deltas| 伸缩。

**替换张量**是命名为
`skill.{skill_id}.{name_of_replaced_tensor}` 的普通目录条目,例如
`skill.sql.model.layers.3.mlp.gate_proj.weight`。被替换张量的完整逻辑形状
(full-shape —— 非低秩、非差异列表、非
掩码),可采用 §3 的任意编码。逐技能增量索引(claim 2)由
目录物化:一次前缀过滤得到 技能 →
字节偏移;惰性分页 = mmap 精确访问那些偏移
(claim 12)。

**注册表** —— 头部 JSON,增量式:

```json
"skills": [{
  "id": "sql",
  "name": "SQL assistant",
  "layers": [3, 4, 5],
  "selection": {"metric": "mse", "phi_layer": 20,
                 "mean": "<f16 base64>", "basis": "<f16 base64>"},
  "input_mask_task": null,
  "quality": {"metric": "ppl", "backbone": 21.4, "overlaid": 17.9,
               "dataset_sha256": "…"}
}]
```

`selection` 保存用于 recon-argmin 路由的仿射子空间参数
(`E = ‖r − BBᵀr‖²/‖φ‖²`,选择 E 最小的技能);
文件对于选择是自足的。`quality` 是诚实的 claim-16
契约(留出数据上的叠加态 vs 骨干)。

**执行语义(claims 1/3/18)**:张量来源间接寻址 —— 对于
每个张量,运行时读取**要么**骨干条目,**要么**存在时的
`skill.{active}.{name}`;是替换而非相加,从不组装
完整的逐技能模型(所有张量都是指向
同一 mmap 的指针)。软叠加(claim 14):混合工作张量
`Σwᵢ·Tᵢ`,`wᵢ = softmax(−E/T)`。

**仅追加式增长(claim 11)**:添加一个技能 = 在文件尾部追加新
张量 + 在尾部重新发出 目录/头部/索引 + 就地
更新信封偏移量(偏移 0 固定)。已写入张量的字节与
偏移量永不改变;旧的 dir/header 字节
成为死区段尾(兼容:读取器只通过
信封导航)。压实(`converter/cmf_compact.py`)= 一次普通重写。

### 9.1 独立技能文件(`SKILL_FILE`,位 6)

技能也可以脱离基座旅行:一个 `.cmf`,其张量集只包含烘焙改变的部分
(加上掩码目录),并通过注册表记录中的身份键绑定到它所裁自的基座:

```json
"skills": [{
  "id": "gfx-html",
  "layers": [0, 1, "...", 21],
  "base_dir_hash": "9f22593eb458bc6f",
  "base_arch": "nanbeige",
  "task": "specialist",
  "provenance": {"corpus": "…", "tensors": 30}
}]
```

- `base_dir_hash` —— 基座文件张量目录字节的 hex `hash64`(信封在
  `[0x78]` 携带的同一值)。技能是针对精确字节的增量,而非针对架构:
  当基座目录哈希不同,`apply` 必须拒绝(显式 `--force` 可覆盖;
  其结果超出规范)。
- `base_arch`、`task`、`provenance` —— 信息键:人工校验、激活的掩码
  任务、来源。

任何带 `base_dir_hash` 的记录都会升起位 6:旧读取器大声拒绝,知道
该位的运行时拒绝运行它(部分张量集不是模型),并指向
`cortiq skill apply <base> <skill> -o out.cmf` —— 验证密钥、把张量与
掩码叠加到基座上、写出完整文件(与技能裁出时的专家逐字节等价)。

生命周期:`skill bake`(专家)→ `skill export --base`(增量 + 密钥)→
发布小文件 → 在任意基座副本上 `skill apply`。

状态:完全实现并把关(容器 + 间接寻址、
生产配方、recon-argmin 路由、仅追加 + 压实、
软混合);claim 16 由测量满足(运行时任务 PPL −24.9%)。

## 10. 分片 —— 一个模型分为 N 个文件

命名:`{base}-{no:05}-of-{count:05}.cmf`(在精神上与
safetensors 兼容)。用户可打开**任意**名称;运行时归一化到分片 1
并按模式拾取兄弟文件。

**每个分片都是一个独立的有效 .cmf**:完整信封、头部 JSON、
一份属于**自己**张量的目录、自己的数据 blob、自己的哈希
(`section_hashes` + 逐张量)。`cortiq verify` 可在没有兄弟文件的情况下
对任意单个分片工作。

每个分片的头部携带:

```json
"shard": { "no": 1, "count": 5 }
```

没有该块 = 一个普通的单文件(向后兼容:旧读取器把
分片 1 视为一个有效但不完整的模型,并在缺失张量处诚实地失败)。

**内容分布**:张量按规范顺序贪婪地拆分
(`--shard-max-gb` 阈值,粗略的 f32 尺寸);masks/vocab/稀疏
索引区段、`tokenizer_config`(聊天捆绑)以及 `skills`
注册表**仅**存在于分片 1 中 —— 其余分片的这些区段为空,且
`tokenizer_config: null`。技能张量(`skill.{id}.*`)作为
普通目录条目分布 —— 分片 1 的注册表通过合并后的目录按名称
引用它们。

**加载**(`CmfModel::open_sharded`):打开分片 1 → mmap 所有兄弟文件
→ 合并目录(每个条目记住其分片索引 —— 一个运行时
字段,绝不写入磁盘)→ 运行时随后如同处理单个
文件一般工作。错误:直接打开一个非首分片、缺失一个兄弟文件、
`count` 不匹配。

Gate(Qwen3.5-0.8B q8_2f,5 个分片 ≤ 0.6 GB):分片化 PPL == 未分片化,
在同一二进制上逐字节相等;`verify` 在每个单独分片上皆为绿。

## 11. 碎片整理——物理剪枝(USPTO App. 19/452,464,claims 9/10 —— [PATENTS.md](../PATENTS.md))

掩码(§5)是**虚拟稀疏**:被剪掉的神经元只是被标记,仍完整存储(所有
任务共享一个骨干——在承诺单一任务之前无法物理切除)。碎片整理把虚拟
稀疏变成**物理压缩**:死 FFN 神经元从文件中删除——**既不存储也不计算**。

**表示——无新特性位,向后兼容。** 物理剪枝只通过目录中更小的张量形状
表达(§3"无可计算布局";目录是形状的唯一权威)。运行时从张量形状
(`gate_proj.rows()`)推导 FFN 尺寸,而非 `arch.intermediate_size`,
因此整理后的文件就是一个普通的更小稠密模型,现有读取器无需修改即可
加载。整理后的文件**没有**掩码节(剪枝后掩码即恒等)。
`arch.intermediate_size` 变为名义值(= 各层最大值);真实尺寸在每个
张量里——且每层收缩到自己的存活神经元数。

**强制不变量:** 每层三元组 `gate_proj.rows() == up_proj.rows() ==
down_proj.cols() == inter'ₗ` 且 `down_proj.rows() == hidden_size`;
神经元轴:`gate/up` 为行、`down` 为列;量化组 32:`inter'` 非 32 倍数
时 `down_proj` 写为 `q8_2f`(转换器自动降级);这不是字节截断——
反量化 → 收集存活神经元 → 在更小形状上**重量化**,张量哈希重新计算;
`hidden_size`、嵌入、`lm_head` 与归一化权重不动。

**一个任务,一个独立文件。** 碎片整理是破坏性的:一个 `.cmf` 只烘焙
一个任务。多任务服务仍走掩码(§5)或技能(§9)。溯源写在
`provenance.defrag` 中(诚实契约)。

**覆盖范围:** 本节为稠密 FFN 神经元;MoE 专家见 §11.1。注意力头
剪枝不在范围内。

### 11.1 MoE 专家碎片整理(`cortiq moe-defrag`)

§11 的 MoE 孪生,由路由 B 场而非神经元掩码驱动:专家使用高度依赖
任务(在 34.7B 代码模型上实测:代码与散文的 top-64 专家集合 Jaccard
仅 0.25),因此单任务文件可以丢弃该任务从不路由到的专家。从
`CMF_MOE_STATS` 转储(代表性任务运行的逐层专家选择计数)出发,每层
保留达到 `--cover` 路由质量分数的最小 top 专家集,丢弃其余。

**表示——同样的哲学,无特性位。**

- 保留的专家重新编号为**连续的逐层前缀** `mlp.experts.0 …
  mlp.experts.{k−1}`,保持相对顺序;读取器按张量**存在性**枚举一层
  的专家,上限为 `arch.moe.num_experts`(变为名义值 = 原始数量)——
  与 §11 对 `intermediate_size` 的规则互为镜像。
- 路由器的行按同一顺序收集:`mlp.gate.weight` 变为 `[kept_l,
  hidden]`,且 `router.rows() ==(存在的专家条目数)`是加载期不变量。
  `top_k` 收缩到逐层专家数。
- 选择语义不变(§2.2):softmax 在保留集合上重新归一化。同一限制可
  在**运行时**应用而无需重写文件(`CMF_MOE_MASK=<stats.json>` +
  `CMF_MOE_MASK_COVER`)——两者在数学上相等,据此在物理切除前用
  困惑度为 cover 水平把关。
- 专家载荷逐字节复制(无需重量化——专家轴切的是整张量而非量化组),
  幸存权重与源逐字节相同,重写从源 mmap 流式进行。

实测参考(KAT-Coder 34.7B-A3B,代码校准,cover 0.95):19.6 → 12.7
GB(−35%),保留集代码困惑度 +2.8%;在 24 GB 内存机器上——完整模型
需要换页——解码 ×1.8、prefill ×3.3。

任务外质量按设计下降;与 §11 一样,一个整理后的文件只烘焙一个任务。

## 12. 流水线容器——单文件文生图

同一套信封/目录/数据块机制承载非 LLM 流水线。区别只有 `arch_name`
标签和张量名的命名空间;没有新节、没有特性位(不执行流水线的读取器
仍可验证与检视文件)。

当前实例——`arch_name: "lumina2-image"`(Lumina-Image 2.0,
`cortiq imagine-pack` / `cortiq imagine`):一个文件装下整个文生图栈。

- **命名空间**`te.*`——文本编码器 Transformer(Gemma-2 类 LLM;
  头部的 `arch` 块描述的正是该组件,通用工具因此能读到有意义的
  维度)、`dit.*`——Next-DiT 去噪器、`vae.*`——VAE 解码器。各组件的
  config JSON 以 `{prefix}.config_json` u8 张量随行——文件自足。
- **量化**:一如既往逐张量(§3 目录即真相)——通常 te/dit 矩阵为
  q4t/q8,VAE 卷积与归一化为 f16。
- **分词器节**(§6)携带文本编码器的分词器;`provenance.pipeline` +
  `provenance.components` 记录配方。

---

*相关:[COMPARISON.md](COMPARISON.md)(CMF 与其他模型格式的对比)、
[项目 README](../README.md)(概览与快速上手)、
`python/cmf_reader.py`(独立读取器:标准库 + numpy,读取所有
dtype、分片、技能、verify)。*