Smollm3:多语言、长上下文的轻量推理模型
HuggingFace 发布的小模型,性能与 Llama 3.1 接近但参数量更小。本地部署和成本优化的新机会。
HuggingFace 发布的小模型,性能与 Llama 3.1 接近但参数量更小。本地部署和成本优化的新机会。
Base model: https://hf.co/HuggingFaceTB/SmolLM3-3B-Base
指令与推理模型: https://hf.co/HuggingFaceTB/SmolLM3-3B
SmolLM3 处于效率最优点。我们的 3B 模型性能优于 Llama-3.2-3B 和 Qwen2.5-3B,同时与更大的 4B 替代品(Qwen3 & Gemma3)保持竞争力。除了性能数字外,我们详细分享了如何使用公开数据集和训练框架构建它的过程。
完整方案:我们发布 SmolLM3 及其工程蓝图。它包括架构细节、确切的数据混合配置,展示了我们在三阶段预训练方法中如何逐步提升各个领域的性能,以及构建混合推理模型的方法论。通常,实现这些结果需要数月的反向工程。而我们直接提供完整的方法论。
无论你是在构建自己的模型还是想理解这个规模下的性能驱动因素,这份蓝图都展示了竞争力 3B 性能背后的工程故事。
让我们看看预训练阶段。
SmolLM3 在其前代版本的基础上改变了架构和数据混合。让我们先看看架构和训练配置!
SmolLM3 遵循 Transformer 解码器架构,采用共享嵌入,与 SmolLM2 类似,基于 Llama 架构,但进行了一些关键优化以提升效率和长上下文性能。
分组查询注意力(GQA):我们用分组查询注意力替代了多头注意力,使用 4 个分组。在用 FineWeb-Edu 的 100B tokens 训练的 3B 模型上进行的消融研究表明,GQA 与多头注意力的性能相当,同时在推理期间显著降低了 KV 缓存大小。
NoPE:我们实现了《RoPE to NoRoPE and Back Again: A New Hybrid Attention Strategy》(Yang et al., 2025)中的 NoPE,选择性地从每第 4 层移除旋转位置嵌入。这种方法改进了长上下文性能,不影响短上下文能力,这一点通过我们的消融研究得到验证。
文档内掩码:根据《Analysing The Impact of Sequence Composition on Language Model Pre-Training》,在训练期间,我们使用注意力掩码确保同一训练序列中来自不同文档的 tokens 不相互注意。与 Llama 3 类似,这有助于更快、更稳定的长上下文训练,同时保持短上下文性能。
训练稳定性:按照 OLMo 2,我们从嵌入层中移除权重衰减以改进训练稳定性。这一改动有助于更稳定的训练动态,嵌入范数在训练中自然稳定在更健康的值,对整体性能没有影响(我们的消融研究证实了这一点)。
所有这些改动都通过消融研究验证过,使用相同的 3B 架构,在 FineWeb-Edu 的 100B tokens 上训练,确保每一项修改要么改进了性能,要么在提供其他优势的同时保持了性能。
训练配置:我们使用 2.36M tokens 的全局批次大小,序列长度为 4096,学习率为 2e-4,AdamW 优化器(beta1: 0.9, beta2: 0.95),权重衰减 0.1,梯度裁剪 1。我们使用 WSD(预热-稳定-衰减)调度器,有 2000 个预热步,在最后 10% 的训练步中线性衰减到 0。我们使用 nanotron 框架进行训练、datatrove 进行数据处理、lighteval 进行评估。模型在 384 块 H100 GPU 上训练了 24 天。你可以在以下图中看到分布式训练设置。
除了架构改动外,我们还改进和消融了训练方案。让我们仔细看看。
按照 SmolLM2 的多阶段方法,我们使用三阶段训练策略在 11.2T tokens 上训练 SmolLM3,混合网页、数学和代码数据,比例不断变化。我们在 3B 模型上进行了大量消融实验,训练数据从 50B 到 100B tokens,以确定数据混合和比例。
预训练包括这些阶段,也如上图所示:
阶段 1:稳定阶段(0T → 8T tokens) 这个基础阶段使用我们的核心数据集混合建立强大的通用能力:
阶段 2:稳定阶段(8T → 10T tokens) 我们引入更高质量的数学和代码数据集,同时保持良好的网页覆盖:
阶段 3:衰减阶段(10T → 11.1T tokens) 最后阶段进一步上采样数学和代码数据
通过这些阶段和混合配置,我们的基础模型实现了非常竞争力的性能。更多内容见评估部分。nanotron 训练配置和确切的数据权重可以在这里找到。我们还会分享训练日志和中间检查点。
在主要预训练后,我们在中间训练阶段改进了模型的长上下文和推理能力。
我们将长上下文适应和推理适应称为"中间训练"。它们比主要预训练短很多,但仍然相当通用,旨在改进模型在这两个领域的能力。让我们先看看长上下文训练。
在主要预训练后,我们用额外 100B tokens 训练 SmolLM3 以扩展其上下文长度。我们分两个阶段顺序扩展上下文窗口,每个阶段 50B tokens:首先从 4k 过渡到 32k 上下文,RoPE theta 增加到 1.5M,然后从 32k 到 64k 上下文,RoPE theta 增加到 5M。两个阶段都上采样了数学、代码和推理数据。在消融实验中,我们发现上采样特定的长上下文数据,如代码库、书籍和长网页(超出我们混合中自然出现的长样本)没有进一步提升 RULER 和 HELMET 基准上的性能。使用 NoPE 和在衰减混合上训练更长的序列以及增加的 RoPE theta 值就足以达到竞争力的长上下文性能,直到 64k。
按照 Qwen2.5 的做法,我们使用 YaRN 外推超出训练上下文长度。在推理期间,模型可以处理长达 128k 的上下文(比 64k 训练长度扩展 2 倍)。
在扩展模型的上下文长度后,我们在中间训练阶段训练它以融入推理能力。中间训练阶段与前期和后期训练阶段的主要区别是我们针对通用能力,而不是尚未聚焦于特定领域。在我们的情况下,我们希望在不针对特定领域(如数学或计算机代码)的情况下训练模型进行推理。
我们的中间训练数据集包含 35B tokens,来自 Open Thought 的 OpenThoughts3-1.2M 和 NVIDIA 的 Llama-Nemotron-Post-Training-Dataset-v1.1 的一个子集,包含来自 R1 的推理轨迹。我们使用了 ChatML 聊天模板和打包方法来避免给模型提供过多结构。我们训练了模型 4 个轮次(~140B tokens)并使用该检查点用于后续的有监督微调阶段。
DeepSeek R1 和 Qwen3 等推理模型的发布展示了当模型能进行显式推理时的强大能力。然而,社区仍然缺乏完全开放的方案和公开数据集来构建同时支持推理和非推理模式的双指令模型。大多数现有方法涉及复杂的强化学习流程和专有数据集,这使得研究人员难以复现和改进这些结果。
在本节中,我们解释了如何应对这些挑战,并分享构建双指令模型的完整方案。我们详细说明如何通过精心设计的训练流水线在推理和非推理模式之间平衡性能,该流水线包括用于通用推理能力的中期训练、带有合成数据生成的监督微调,以及使用 Anchored Preference Optimization (APO)(DPO 的最新变体)的对齐。
在深入探讨训练方法之前,必须明确用户如何与我们的双模式模型交互。聊天模板充当接口,使推理和非推理模式之间的无缝切换成为可能,其设计直接影响我们的训练数据格式和模型行为。SmolLM3 的聊天模板允许用户在对话中控制推理模式。用户可以通过在系统提示中分别包含 /think 和 /no_think 标志来激活推理或非推理模式。在非推理模式中,我们用空的 think 块预填充模型的响应(类似于 Qwen3),以确保直接答案而不进行显式推理。
SmolLM3 支持工具调用,其聊天模板包含两个不同的工具描述部分:XML 工具和 Python 工具。在我们的实验中,这种特定的分类对模型准确解释每种格式的工具定义有所帮助。
聊天模板为两种推理模式提供默认的系统消息,以及包含日期、知识截断日期和当前推理模式的元数据部分。用户可以通过提供具有系统角色的消息来替换默认系统消息。可以通过在系统提示中使用 /system_override 标志来排除元数据部分,为特定用例提供灵活性。
在推理中期训练阶段(我们在 140B tokens 的通用推理数据上训练了模型)之后,我们继续进行监督微调(SFT),以在推理和非推理模式中融合数学、代码、通用推理、指令遵循、多语言和工具调用的能力。训练双模式模型需要仔细平衡数据混合,以在所有目标领域的两种模式中保持强劲性能。为了在整个训练过程中评估 SmolLM3 的性能,我们跟踪了以下领域:数学、代码、通用推理、指令遵循和多语言。
在构建推理模式数据集时遇到的主要挑战是某些领域缺乏包含推理轨迹的数据集。为了弥补这一空缺,我们通过使用现有非推理数据集的提示在推理模式下提示 Qwen3-32B 来生成合成数据。这使我们能够改进模型在推理模式中最初苦恼的领域的性能,如多轮对话、多语言和日常对话。
我们的最终数据混合是通过广泛的消融研究得出的,该研究检查了推理到非推理 tokens 的最优比例及每种模式内的组成。生成的 SFT 数据集包含 1.8B tokens:非推理模式 1B,推理模式 0.8B,包含 12 个非推理数据集和 10 个具有推理轨迹的数据集。我们使用 BFD(最佳递减拟合)打包进行了 4 个 epoch(~8B tokens)的训练,损失在用户轮次和工具调用结果上被掩盖。
我们将发布这个数据混合及完整的训练脚本,以使社区能够复现和改进我们的工作。
SFT 步骤之后,我们使用 Tulu3 偏好数据集(用于非推理模式)和从 Qwen3-32B 和 Qwen3-0.6B 生成的新合成偏好对(用于推理模式)的组合进行了一轮模型对齐。为了确保非思考数据集中所有领域的完全覆盖,我们生成了补充的思考模式偏好对。我们选择 Qwen3-32B 的生成作为"选择的",Qwen3-0.6B 的响应作为"拒绝的",用于 Anchored Preference Optimization 的对齐。
Anchored Preference Optimization (APO) 是 Direct Preference Optimization (DPO) 的一个变体,提供了更稳定的优化目标。在 DPO 中,奖励函数 r_θ(x,y) 测量训练期间序列概率与训练开始时模型(参考模型)的对数比:
这里 β 控制被优化的模型相对于参考模型可以改变多少。DPO 损失优化提示 x、选择的 y_w 和拒绝的 y_l 响应的三元组:
APO 目标已被证明更加稳定,我们在内部消融中也观察到了更高的下游性能。
虽然下游评估显示在数学、科学、指令遵循、编码、聊天和多语言任务中的性能改进,但我们在长上下文基准(如 RULER)上观察到性能下降。我们将这种下降追溯到推理中期训练阶段,其中对推理能力的关注影响了长上下文性能。此外,APO 训练数据限制在 24k tokens,因为我们的推理数据集的绝大多数都低于此长度。
为了缓解这种性能下降,我们探索了模型合并作为解决方案。
模型合并是一种流行和强大的技术,允许在不增加集成计算开销或需要额外训练的情况下结合不同模型的优势。我们使用 MergeKit 库来执行模型合并,因为它包含多种合并方法,包括线性和非线性合并。
我们的合并方案包括两个步骤:
获取每个 APO 检查点并创建一个模型"汤"。
将模型汤与具有强长内容性能的中期训练检查点相结合。对于 APO 模型汤和中期训练检查点,分别使用权重 0.9 和 0.1 的线性合并实现了最佳性能。我们能够在最高 128k tokens 的上下文上恢复基础模型的 RULER 分数。
生成的模型是我们今天发布的检查点。它在广泛的任务中保持性能。现在让我们转向该模型和基础模型的评估结果。
我们在推理和非推理模式下对基础模型和指令模型进行了评估。让我们首先介绍基础模型的性能!
下面的图表显示了 SmolLM3 在 12 个流行基准中的胜率,这些基准评估知识、推理、数学和编码能力。SmolLM3 始终优于其他 3B 模型,并相对于包括 Qwen3-4B 和 Gemma3-4B 在内的较大 4B 模型实现了竞争性能。
用于胜率的评估基准:HellaSwag、ARC、Winogrande、CommonsenseQA、MMLU-CF、MMLU Pro CF、PIQA、OpenBookQA、GSM8K、MATH、HumanEval+、MBPP+
SmolLM3 在知识和推理基准(HellaSwag、ARC、BoolQ)上获得第一或第二名,展示了这些核心能力的强劲性能。数学和编码性能在 3B 级中具有竞争力。Ruler 64k 上的长上下文性能显示该模型可以有效处理扩展序列。
当在多语言基准(包括 Global MMLU、MLMM HellaSwag、Flores-200、Belebele)上进行评估时,该模型在五种主要欧洲语言中展示了强大的多语言性能,测试知识、常识推理、文本理解和翻译。这表明 SmolLM3 在英语之外保持一致的性能。
总之,基础模型在许多领域显示出非常强大的性能。让我们看看这如何转化为指令模型的性能。
由于 SmolLM3 具有指令和推理模式,我们需要在两种模式中评估模型并与具有相同功能的模型进行比较。
我们将 SmolLM3 与其他 3B 非推理模型进行比较,并在多个基准中将其与 Qwen3 推理模型在无思考模式下进行比较。如性能图表所示,SmolLM3 优于其他 3B 非推理模型(包括 Llama3.2 3B Instruct 和 Qwen2.5 3B Instruct),并处于推理模型之间的效率最佳点,明显优于 Qwen3 1.7B,同时以更低的计算成本接近 4B 模型性能。
因此,该指令模型正好处于性能与成本的帕累托前沿。接下来看看推理模型的表现!
在启用扩展思考的情况下评估 SmolLM3 的推理能力时,与非推理版本相比,该模型在大多数基准测试中都有显著提升。我们观察到,它在 AIME 2025(36.7% 对 9.3%)、LiveCodeBench 竞技编程(30.0% 对 15.2%)以及 GPQA Diamond 研究生级推理(41.7% 对 35.7%)等高难度任务上取得了明显进步。
虽然 Qwen3 4B 在思考和非思考模式下通常都能取得最高分,但 SmolLM3 在 3B 参数量级中展现出了有竞争力的性能,尤其擅长数学推理和复杂问题求解任务。该模型的双模式能力允许用户在不进行推理、速度更快的推理过程与启用扩展思考、分析更深入的推理过程之间进行选择。
那么最后一个问题是:如何使用这个模型?
SmolLM3 的建模代码已在 transformers v4.53.0 中提供,因此请确保升级你的 transformers 版本。你也可以使用最新版 vllm 加载该模型,它使用 transformers 作为后端。
pip install -U transformers
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "HuggingFaceTB/SmolLM3-3B"
device = "cuda" # for GPU usage or "cpu" for CPU usage
# load the tokenizer and the model
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
).to(device)
# prepare the model input
prompt = "Give me a brief explanation of gravity in simple terms."
messages_think = [
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
messages_think,
tokenize=False,
add_generation_prompt=True,
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
# Generate the output
generated_ids = model.generate(**model_inputs, max_new_tokens=32768)
# Get and decode the output
output_ids = generated_ids[0][len(model_inputs.input_ids[0]) :]
print(tokenizer.decode(output_ids, skip_special_tokens=True))
我们建议在采样参数中设置 temperature=0.6 和 top_p=0.95。
我们默认启用扩展思考,因此上面的示例会生成包含推理轨迹的输出。要选择是否启用扩展思考,可以通过系统提示词传入 /think 或 /no_think 标志。下面的代码片段展示了禁用扩展思考的情况。生成启用扩展思考的响应时,代码保持不变,只需在系统提示词中使用 /think,而不是 /no_think。
prompt = "Give me a brief explanation of gravity in simple terms."
messages = [
{"role": "system", "content": "/no_think"},
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
)
SmolLM3 支持工具调用!只需通过参数 xml_tools 传入工具列表(用于标准工具调用),或者通过 python_tools 传入工具列表(用于调用类似 Python 函数的工具,并将调用放在 <code> 代码片段中)。
from transformers import AutoModelForCausalLM, AutoTokenizer
checkpoint = "HuggingFaceTB/SmolLM3-3B"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForCausalLM.from_pretrained(checkpoint)
tools = [
{
"name": "get_weather",
"description": "Get the weather in a city",
"parameters": {"type": "object", "properties": {"city": {"type": "string", "description": "The city to get the weather for"}}}}
]
messages = [
{
"role": "user",
"content": "Hello! How is the weather today in Copenhagen?"
}
]
inputs = tokenizer.apply_chat_template(
messages,
enable_thinking=False, # True works as well, your choice!
xml_tools=tools,
add_generation_prompt=True,
tokenize=True,
return_tensors="pt"
)
outputs = model.generate(inputs)
print(tokenizer.decode(outputs[0]))
我们发布了 SmolLM3——一个小型、支持长上下文和多语言的推理模型,上下文长度最高可达 128k。除了模型检查点之外,我们还发布了完整的训练方案,其中包括预训练、中期训练、后训练和合成数据生成流程,以及相关数据集(即将发布)。我们希望这个模型能为社区带来帮助,也希望这套方案能让其他团队在此基础上继续改进。
包含量化检查点的模型合集:链接
包含预训练配置和评估代码的 SmolLM GitHub 仓库:https://github.com/huggingface/smollm
我们的 HuggingFace 组织主页:https://huggingface.co/HuggingFaceTB
@misc{bakouch2025smollm3,
title={{SmolLM3: smol, multilingual, long-context reasoner}},
author={Bakouch, Elie and Ben Allal, Loubna and Lozhkov, Anton and Tazi, Nouamane and Tunstall, Lewis and Patiño, Carlos Miguel and Beeching, Edward and Roucher, Aymeric and Reedi, Aksel Joonas and Gallouédec, Quentin and Rasul, Kashif and Habib, Nathan and Fourrier, Clémentine and Kydlicek, Hynek and Penedo, Guilherme and Larcher, Hugo and Morlon, Mathieu and Srivastav, Vaibhav and Lochner, Joshua and Nguyen, Xuan-Son and Raffel, Colin and von Werra, Leandro and Wolf, Thomas},
year={2025},
howpublished={\url{https://huggingface.co/blog/smollm3}}
}
本文提及的模型 3
本文提及的数据集 5
本文提及的论文 2
本文提及的合集 1
mmBERT:ModernBERT 迈向多语言
Ettin Suite:SoTA 成对编码器和解码器
太不可思议了!谢谢。
写得真棒。绝对要加入周末阅读清单!
干得漂亮!我有一个问题,也是出于好奇。在训练期间将模型拆分到两块 GPU 上有什么优势?(文中提到,你们在每个包含 8 块 GPU 的节点上使用张量并行(TP)为 2、数据并行(DP)为 4 的配置。)我猜这个模型比较小,应该能放进单块 GPU?我原本以为在这种情况下,最高效的实现方式应该是使用 DP=8?
训练时,这个模型无法放进单块 GPU(除非使用 ZeRO/激活重计算),而且 TP=2 对吞吐量的影响不大,因此我们选择了这个方案。你可以在这里找到更多有关分布式预训练的信息:https://huggingface.co/spaces/nanotron/ultrascale-playbook
哇,进展很棒,文章也写得非常精彩!
感谢分享!!!我可能发现了一个小错误,是否应该把 “To ensure full coverage of all domains in t