AI 大模型文件里到底装了什么:671B 参数、几十 GB 的文件,拆开给你看

AI 大模型文件里到底装了什么:671B 参数、几十 GB 的文件,拆开给你看

AI 大模型文件里到底装了什么:671B 参数、几十 GB 的文件,拆开给你看

适合对 AI 大模型好奇、想知道模型文件内部结构的开发者。
本文用 Python 实际加载和分析模型文件,展示参数、权重、配置的结构。

背景:模型文件是个黑盒

下载一个开源大模型(如 DeepSeek-V3、Qwen2.5),你会得到一堆文件:

model-00001-of-00006.safetensors model-00002-of-00006.safetensors ... config.json tokenizer.json

这些文件里到底装了什么?671B 参数是什么意思?为什么一个模型要几十 GB?

今天拆开看。

模型文件的组成

一个完整的模型包含 4 类文件:

文件作用大小占比
模型权重(.safetensors/.bin)神经网络的所有参数95%+
配置文件(config.json)模型架构参数< 0.01%
词表文件(tokenizer.json)Token 和 ID 的映射< 1%
其他文件许可证、README 等< 0.01%

1. 配置文件(config.json)

importjsonwithopen("config.json")asf:config=json.load(f)# DeepSeek-V3 的配置(示例)print(json.dumps(config,indent=2))

输出示例:

{"model_type":"deepseek_v3","hidden_size":7168,"num_hidden_layers":61,"num_attention_heads":128,"num_key_value_heads":128,"intermediate_size":18432,"vocab_size":129280,"max_position_embeddings":163840,"rms_norm_eps":1e-6,"rope_theta":10000.0}

关键参数解读

参数含义DeepSeek-V3 值
hidden_size每个 token 的向量维度7168
num_hidden_layersTransformer 层数61
num_attention_heads注意力头数128
intermediate_sizeFFN 中间层维度18432
vocab_size词表大小129280
max_position_embeddings最大上下文长度163840

参数量估算

# 简化估算公式defestimate_params(config):h=config["hidden_size"]# 7168L=config["num_hidden_layers"]# 61V=config["vocab_size"]# 129280I=config["intermediate_size"]# 18432# 每层参数 ≈ 4 * h^2 + 2 * h * I(Attention + FFN)params_per_layer=4*h**2+2*h*I# 总参数 ≈ 层数 * 每层 + embedding + outputtotal=L*params_per_layer+2*V*hreturntotal params=estimate_params(config)print(f"估算参数量:{params/1e9:.1f}B")# 约 671B

2. 模型权重(safetensors 文件)

fromsafetensorsimportsafe_open# 加载第一个权重文件withsafe_open("model-00001-of-00006.safetensors",framework="numpy")asf:# 列出所有参数名keys=f.keys()print(f"参数数量:{len(keys)}")# 查看前 10 个参数名forkeyinlist(keys)[:10]:tensor=f.get_tensor(key)print(f"{key}: shape={tensor.shape}, dtype={tensor.dtype}")

输出示例:

参数数量: 3256 model.embed_tokens.weight: shape=(129280, 7168), dtype=float16 model.layers.0.self_attn.q_proj.weight: shape=(7168, 7168), dtype=float16 model.layers.0.self_attn.k_proj.weight: shape=(7168, 7168), dtype=float16 model.layers.0.self_attn.v_proj.weight: shape=(7168, 7168), dtype=float16 model.layers.0.self_attn.o_proj.weight: shape=(7168, 7168), dtype=float16 model.layers.0.mlp.gate_proj.weight: shape=(18432, 7168), dtype=float16 model.layers.0.mlp.up_proj.weight: shape=(18432, 7168), dtype=float16 model.layers.0.mlp.down_proj.weight: shape=(7168, 18432), dtype=float16 model.layers.0.input_layernorm.weight: shape=(7168,), dtype=float32 model.layers.0.post_attention_layernorm.weight: shape=(7168,), dtype=float32

参数命名规则

model.layers.{层号}.{模块}.{参数类型}
模块含义参数形状
self_attn.q_projQuery 投影(hidden_size, hidden_size)
self_attn.k_projKey 投影(hidden_size, hidden_size)
self_attn.v_projValue 投影(hidden_size, hidden_size)
self_attn.o_projOutput 投影(hidden_size, hidden_size)
mlp.gate_projFFN 门控(intermediate_size, hidden_size)
mlp.up_projFFN 上投影(intermediate_size, hidden_size)
mlp.down_projFFN 下投影(hidden_size, intermediate_size)
input_layernorm输入归一化(hidden_size,)

3. 为什么模型这么大

defcalculate_model_size(config):"""计算模型存储大小"""h=config["hidden_size"]L=config["num_hidden_layers"]V=config["vocab_size"]I=config["intermediate_size"]# 每层参数数量attn_params=4*h*h# Q, K, V, Offn_params=3*h*I# gate, up, downnorm_params=2*h# 2 个 LayerNormlayer_params=attn_params+ffn_params+norm_params# 总参数total_params=L*layer_params+V*h# 层 + embedding# FP16 存储(2 字节/参数)size_fp16=total_params*2/(1024**3)# GB# INT4 量化存储(0.5 字节/参数)size_int4=total_params*0.5/(1024**3)# GBprint(f"总参数:{total_params/1e9:.1f}B")print(f"FP16 存储:{size_fp16:.1f}GB")print(f"INT4 量化:{size_int4:.1f}GB")returntotal_params# DeepSeek-V3config={"hidden_size":7168,"num_hidden_layers":61,"vocab_size":129280,"intermediate_size":18432}calculate_model_size(config)# 输出:# 总参数: 671.0B# FP16 存储: 1243.1 GB# INT4 量化: 310.8 GB

所以 DeepSeek-V3 全精度需要 1.2TB 存储,INT4 量化后需要约 311GB。

4. 词表文件(tokenizer.json)

withopen("tokenizer.json")asf:tokenizer_data=json.load(f)# 词表大小vocab=tokenizer_data.get("model",{}).get("vocab",{})print(f"词表大小:{len(vocab)}")# 查看一些 tokensample_tokens=list(vocab.items())[:20]fortoken,token_idinsample_tokens:print(f" '{token}' → ID{token_id}")

输出示例:

词表大小: 129280 '!' → ID 0 '"' → ID 1 '#' → ID 2 '$' → ID 3 '我' → ID 452 '是' → ID 374 'Python' → ID 15339

词表的作用:把文本拆成 token(ID),模型处理的是 ID 序列,输出的也是 ID 序列,再通过词表转回文本。

5. 模型加载过程

fromtransformersimportAutoModelForCausalLM,AutoTokenizerimporttorch# 加载 tokenizer(词表)tokenizer=AutoTokenizer.from_pretrained("./model_dir")# 加载模型权重model=AutoModelForCausalLM.from_pretrained("./model_dir",torch_dtype=torch.float16,# 用 FP16 节省显存device_map="auto"# 自动分配到 GPU)# 查看模型结构print(model)# 输出:# DeepSeekForCausalLM(# (model): DeepSeekModel(# (embed_tokens): Embedding(129280, 7168)# (layers): ModuleList(# (0): DeepSeekDecoderLayer(...)# (1): DeepSeekDecoderLayer(...)# ...# )# (norm): RMSNorm()# )# (lm_head): Linear(7168, 129280, bias=False)# )

6. 量化是怎么回事

量化就是用更少的比特数存储每个参数,减小模型体积和显存需求。

精度每个参数占空间671B 模型大小质量损失
FP324 字节2.5 TB
FP162 字节1.2 TB极小
INT81 字节620 GB
INT40.5 字节311 GB中等
INT20.25 字节155 GB较大
# 量化示例(使用 bitsandbytes)fromtransformersimportBitsAndBytesConfig quant_config=BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_compute_dtype=torch.float16)model=AutoModelForCausalLM.from_pretrained("./model_dir",quantization_config=quant_config,device_map="auto")# 查看显存占用print(f"显存占用:{model.get_memory_footprint()/1e9:.1f}GB")

踩坑记录

坑 1:safetensors 和 .bin 格式混淆

症状:下载的模型既有 .safetensors 又有 .bin,不知道用哪个。

原因:旧版用 PyTorch 的 .bin 格式,新版用 safetensors(更安全)。

解决:优先用 .safetensors,它是 safetensors 库的格式,加载更安全(不会执行恶意代码)。

坑 2:模型文件不完整

症状:加载时报 “unexpected key” 或 “missing key”。

原因:下载中断,文件不完整。

解决:检查文件 hash,或者重新下载。

坑 3:显存不够加载整个模型

症状:加载 70B 模型时报 CUDA out of memory。

解决

  1. 用量化(INT4/INT8)
  2. device_map="auto"自动分层到 CPU 和 GPU
  3. 用 llama.cpp 等 CPU 推理工具

坑 4:不同框架的权重格式不通用

症状:HuggingFace 格式的模型在 llama.cpp 里用不了。

原因:不同框架的权重命名和排列方式不同。

解决:用转换工具(如convert-hf-to-gguf.py)转换格式。

坑 5:config.json 里的参数和实际权重不匹配

症状:config 写了 32 层,但权重文件只有 30 层的参数。

原因:模型经过剪枝或微调后 config 没更新。

解决:以实际权重文件为准,config 只是参考。

总结

3 条核心经验:

  1. 模型 = 配置 + 权重 + 词表。配置定义架构,权重存储知识,词表做文本↔ID 转换。

  2. 模型大小 = 参数量 × 精度。671B 参数在 FP16 下需要 1.2TB,INT4 量化后只需 311GB。量化是让大模型能在消费级硬件上跑的关键。

  3. safetensors 是目前最好的权重格式。比 .bin 更安全、加载更快,优先使用。


你对大模型内部结构有什么疑问?评论区交流。