【免费下载链接】Llama-3.2-1B
Llama-3.2-1B 是 Meta 开源的 10 亿参数大语言模型,最大亮点是支持 131K(131072)超长上下文窗口,靠的是 rope_type: llama3 这种"高低频分开处理"的 RoPE 缩放方案。本文带你读懂 config.json 里那 5 个参数,并亲手算出 8192 → 131072 的推算过程。
先看答案:config.json 里的关键配置
Llama-3.2-1B 的全部"上下文能力"都写在模型配置文件里,打开 config.json 你会看到:
| 配置项 | 值 | 含义 |
|---|---|---|
max_position_embeddings | 131072 | 支持的最大上下文长度(128K) |
rope_theta | 500000.0 | RoPE 旋转基准频率(base) |
rope_scaling.rope_type | llama3 | 采用 llama3 混合缩放方案 |
rope_scaling.factor | 32.0 | 位置编号整体放大 32 倍 |
rope_scaling.original_max_position_embeddings | 8192 | 原始训练时的上下文长度 |
rope_scaling.high_freq_factor | 4.0 | 高频部分按 4 倍插值 |
rope_scaling.low_freq_factor | 1.0 | 低频部分不缩放 |
📌 131072 恰好等于 2^17,也就是俗称的 128K token;generation_config.json 中
max_length: 131072与之完全一致。
为什么 1B 小模型也能"读" 131K 文本?
RoPE(旋转位置编码)给每个 token 的位置打上"旋转角度":角度 = 位置 × 频率。频率越高的维度转得越快,负责分辨相邻位置(高频,细节);频率越低的维度转得越慢,负责分辨远距离位置(低频,全局结构)。
问题在于:模型只见过 8192 个位置,直接外推到 131K 会让慢转维度"转不够一圈"、快转维度"糊成一团"。传统 NTK 方案是把所有频率统一除以 32 倍开方数,简单但会损失局部细节。Llama-3.2 的 llama3 方案更聪明:快频率当"细节"保护起来只做轻度插值,慢频率当"全局"完全不碰。
第一步:算出 32 个维度的原始频率
每个注意力头 64 维(config.json head_dim: 64),对应 32 对 (cos, sin)。第 i 对频率由公式决定:
θᵢ = base^(-2i/d),其中 base =
rope_theta= 500000,d = 64
逐项计算(i = 0 ~ 31):
| 维度对 i | 频率 θᵢ(Hz) | 转一圈需要的 token 数 | 角色 |
|---|---|---|---|
| 0 | 1.00 | 6283 | 最快 |
| 1 | 1.49 | 4209 | 高频 |
| 8 | 26.6 | 236 | 高频 |
| 16 | 707.1 | 9.0 | 分界线附近 |
| 18 | 1605.7 | 4.0 | 低频开始 |
| 19 | 2419.7 | 2.6 | 低频 |
| 20 | 3646.3 | 1.72 | 低频 |
| 31 | 331800.7 | 0.019 | 最慢 |
可以看到频率从 1 一路拉到 33 万,跨越 5 个数量级——这正是"快慢维度分工"的源头。
第二步:定位高频/低频分界线
llama3 方案的分界线定义是:"旋转周期恰好等于原始最大长度 8192 的那个维度"。
设维度 i 的周期为 2π/θᵢ,令 2π/θᵢ = 8192,解得临界频率:
θ* = 2π ÷ 8192 ≈ 0.000766(Hz)
对照上表,维度对 18 的频率 1605.7 与维度对 19 的 2419.7 正好跨过了这个临界值,因此:
- 高频部分:i = 18, 19, …, 31(转得快的 14 对)
- 低频部分:i = 0, 1, …, 17(转得慢的 18 对)
工程实现中这一步通常写成 low_freq_idx = floor(d/2 × log(base/period) / log(base)),在 base=500000、period=8192 时同样落在 i=18 处。
第三步:对高频部分做 NTK 插值
对高频维度使用 NTK 公式,等价于把频率"压扁" factor^(2/d) 倍:
θ'ᵢ = θᵢ ÷ factor^(d/2) = θᵢ ÷ 32^(1/32) ≈ θᵢ ÷ 1.1126
| 维度对 i | 原始频率 | 缩放后频率(÷1.1126) |
|---|---|---|
| 18 | 1605.7 | ≈ 1443.1 |
| 19 | 2419.7 | ≈ 2174.8 |
| 31 | 331800.7 | ≈ 298223.5 |
注意分母只是 1.1126——因为 32 的 1/32 次方非常接近 1,所以高频部分只被"轻轻压"了一下,细节损失极小。
第四步:低频部分原样保留
low_freq_factor: 1.0 表示低频维度(i = 0 ~ 17)频率完全不变,1.0、1.49、26.6……707.1 全部照旧。
为什么敢这么"硬"?因为最慢的维度(i=17)周期约为 8.9 token,131K 个位置足以让它转上上万圈,慢维度根本不缺"距离分辨力",不需要任何插值。
第五步:位置编号 ×32,8K 到 131K 的推算闭环
最后也是最反直觉的一步:factor: 32.0 并不直接乘频率,而是乘位置编号——模型内部先计算 scaled_pos = pos × 32,再用缩放后的频率对 scaled_pos 做旋转:
- 原始训练:位置 0 ~ 8191(覆盖 8K)
- 缩放后:实际位置 0 ~ 131071 → 内部坐标 0 ~ 4194304(≈ 420 万)
验证两个边界:
- 高频快转维度:缩放后最慢的高频维度(i=18)在 131K 处已转了 131072 × 1.443 rad/步,远超 8192 内见过的旋转量,没有"外推盲区";
- 低频慢转维度:位置坐标被放大 32 倍后,即便周期只有 9 个 token 的维度,在 420 万内部坐标里也转了几十万圈,依旧处于"熟悉区"。
于是 8192 → 131072 的 32 倍窗口扩展,被拆解为"位置 ×32 外推 + 高频 ÷1.1126 轻度压缩 + 低频不动"的三合一方案,既保住 8K 内的局部细节,又支撑起 131K 的全局距离感知——这就是 rope_type: llama3 的完整原理。
顺带一提:1B 模型跑 131K 有多省?
Llama-3.2-1B 只有 16 层、8 个 KV 头、每头 64 维(config.json),且全部采用 GQA 分组查询注意力。粗算 KV Cache:
2(K+V)× 16 层 × 8 头 × 64 维 × 2 字节(bf16)× 131072 token ≈ 4 GiB
也就是说,一个 1B 小模型吃满 128K 上下文时,注意力缓存只要 4 GiB 左右——这正是小参数量 + 长上下文组合能在消费级显卡上本地运行的关键。
总结:3 句话看懂 llama3 缩放
- 分界:以"周期 = 8192"为界,把 32 对频率分成 18 低频 + 14 高频两组;
- 高频轻压:高频组频率除以 32^(1/32) ≈ 1.1126,仅做 NTK 式温和插值;
- 低频不动 + 位置 ×32:低频频率保持原样,位置编号整体放大 32 倍,把 8K 训练经验"平滑外推"到 131K。
理解了这套机制,你再看 config.json 里的 rope_scaling 配置时,每个数字都会变得有迹可循——下次想复现或修改模型的上下文长度,从这 5 个参数入手就对了。
【免费下载链接】Llama-3.2-1B
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



