模型基因组:如何识别大模型是从零训练还是衍生而来?
引言:一个值得追问的问题
在开源权重(如Qwen、Llama、DeepSeek、Mistral)基础上构建大语言模型,是业界普遍且合理的做法。但这与从零训练一个基础模型有着本质区别——而厂商并不总是明确说明这一点。2026年7月底,多家实验室发布了号称对标DeepSeek的“自主研发”模型(如LG的K-EXAONE 2.0,750B参数),这一话题在国内技术社区也引发了热议,知乎上一个相关问题的浏览量已超过270万。随之而来的自然疑问是:这些模型究竟是从零训练,还是基于开源模型衍生而来?
这个问题其实可以通过公开文件客观地回答。本文将介绍一套可复现的检测流程,从三个维度对模型进行“指纹”识别,并组合成一个直观的“基因型”。
维度一:架构指纹(config.json)
每个基于transformers的模型检查点都会附带一个config.json文件。其中几个关键字段构成了极具区分度的签名:
model_typevocab_sizehidden_sizeintermediate_sizenum_hidden_layersnum_attention_heads/num_key_value_heads
我们可以通过以下代码提取这些字段:
import requests
def arch_fingerprint(repo):
c = requests.get(f"https://huggingface.co/{repo}/resolve/main/config.json",
headers={"User-Agent": "genome/1.0"}).json()
return {k: c.get(k) for k in
("model_type", "vocab_size", "hidden_size",
"intermediate_size", "num_hidden_layers",
"num_attention_heads", "num_key_value_heads")}形状元组(hidden_size, intermediate_size, num_hidden_layers, heads, kv)实际上就是参考架构的指纹。当某个模型的元组与某个国外开源权重完全一致时,这强烈表明其架构是采用而非独立设计的。我们实测的一些案例如下:
| 模型 | 形状 (h · i · L · heads · kv) | 精确匹配 |
|---|---|---|
| 某7B商业模型 | 3584 · 18944 · 28 · 28 · 4 | Qwen2.5-7B |
| 某72B商业模型 | 8192 · 29568 · 80 · 64 · 8 | Qwen2.5-72B |
| 某14B VLM | 5120 · 17408 · 40 · 40 · 8 | Qwen3-14B |
| 某8B模型 | 4096 · 14336 · 32 · 32 · 8 | Llama-3.1-8B |
| 某MoE模型 | 7168 · 18432 · 61 · (moe 2048) | DeepSeek-V3 |
单个字段的巧合说明不了问题,但五个字段同时匹配,那就是指纹级别的证据了。
维度二:分词器指纹(亲子鉴定)
仅凭架构可能会产生误导。一个模型可能复制了国外的架构,但训练了全新的分词器,反之亦然。分词器可以直接从tokenizer.json中测量,通过比较词汇表集合,计算最小重叠率:
def vocab_set(repo):
j = requests.get(f"https://huggingface.co/{repo}/resolve/main/tokenizer.json").json()
v = j["model"]["vocab"] # BPE: {token: id}
return set(v.keys())
def tok_overlap(a, b):
A, B = vocab_set(a), vocab_set(b)
return len(A & B) / min(len(A), len(B)) # 1.0 == subset这能立刻揭示config隐藏的信息。有一个模型在架构上与Qwen2.5-7B完全匹配,但其分词器与Qwen的重叠率仅为约0.38——这是一个“外国大脑,自有语言”的案例:架构是采用的,但训练了新的韩语分词器。相反,一些VLM直接复用了基础分词器(重叠率=1.000),证实了它们是直接微调而来。
一个实用陷阱:分母使用
min(|A|,|B|)(而非并集),这样才能让一个较大词汇表的严格子集(即缩减后的词汇表)得分接近1.0——这才是“从基础模型中裁剪出来”的正确信号。
维度三:权重指纹(难点所在)
最核心的问题是:权重是从零训练的,还是在国外基础模型上继续预训练的? 这里有两个值得注意的陷阱。
陷阱一:逐行余弦相似度无效
一个天真的想法是:加载两个模型的embed_tokens.weight,对于共享的token,计算逐行余弦相似度的平均值。如果它们有共同的血统,嵌入应该相似。
但事实并非如此——即使它们明显有共同血统。我们测量到,无论是已知从零训练的模型,还是已知的Llama衍生模型,其平均余弦都接近零。原因是旋转不变性:Transformer的隐藏空间没有特权基,两个模型可以在任意正交旋转下编码相同的信息。逐行余弦将旋转视为不相似,因此无法区分血统。
陷阱二:CKA有帮助,但还不够
线性CKA(中心核对齐) 具有旋转不变性和各向同性缩放不变性,因此是比较表示的正确工具:
import torch
def linear_cka(X, Y):
# X: (n, d1), Y: (n, d2) — 相同的token顺序(共享词汇表)
X = X - X.mean(0, keepdim=True)
Y = Y - Y.mean(0, keepdim=True)
num = (X.T @ Y).norm() ** 2
den = (X.T @ X).norm() * (Y.T @ Y).norm()
return (num / den).item()一个从零训练的模型与其候选基础模型之间的CKA得分接近零——这是独立预训练的干净证据。但一个继续预训练的衍生模型得分仅略高(约0.25)——几乎与同一家族两个不相关模型之间的基线(约0.21)相当。大规模训练会重塑嵌入,使得CKA在衍生侧失去了区分能力。
结论(诚实地说): 权重轴能可靠地确认从零训练(接近零),但不是检测衍生的强有力工具。因此,config和分词器指纹仍是主要证据。我们将权重轴作为辅助证据,而非独立结论。
附加维度:注意力多样性作为原创性代理
大多数模型声明单一的注意力机制,少数则混合多种。config.json中不同机制的数量可以作为架构原创性的廉价代理:
KEYS = ("layer_types", "linear_attn_config", "sliding_window",
"mamba2_d_state", "hyena_filter_order", "mla_kv_lora_rank",
"attention_cls")
def attention_diversity(cfg):
hits = [k for k in KEYS if k in cfg]
# 例如 layer_types = [full×16, sliding×48] -> hybrid (2)
return hits在我们的扫描中,大多数韩国模型使用单一的组查询或多头潜在注意力;少数使用混合(layer_types = [full_attention×16, sliding_attention×48]);最多样化的在一个堆栈中结合了mamba2、hyena、MLA、线性注意力、门控DeltaNet、原生稀疏注意力和滑动窗口。
组合维度:基因型
我们将两个主要维度(架构×权重)合并为一个标签:
| 基因型 | 架构 | 权重 |
|---|---|---|
| 🟢 原生 | 自研 | 从零训练 |
| 🔵 改编 | 基本自研 | 一个轴借用 |
| 🟡 混合 | 部分 | 部分继承 |
| 🔴 移植 | 国外(精确匹配) | 继承 |
分词器重叠和注意力多样性作为辅助信息展示,不纳入最终判定,以便读者看到原始证据。
结果
我们将相同的流程应用于九家韩国机构(大型企业、电信公司、中型企业和初创公司)的公开基础模型,结果并非千篇一律:有些模型在架构和分词器上都与国外模型完全匹配(移植);有些使用自研架构和权重,无国外匹配(原生);许多介于两者之间。每个模型的详细分解——包括3D血缘图、搜索和明暗模式——可在Space中查看。
诚实与局限
- 这不是指控。 基于开源权重构建是合法且普遍的。该工具报告的是血缘关系,而非不当行为。
- 权重轴是辅助性的,而非结论性的(见第4节)。
- 对每个模型使用相同的标准,无一例外。
- 所有输入均为公开数据,欢迎指正。
复现方法
上述三个函数就是全部方法。将它们指向Hub上的任意两个仓库即可:
print(arch_fingerprint("some/model"))
print(tok_overlap("some/model", "Qwen/Qwen3-14B"))
# 权重:加载共享词汇表对的 embed_tokens.weight,然后计算 linear_cka在线演示、完整数据集和三语言界面:Model Genome Korea。
模型名称、公司和许可证归各自所有者所有。