一张 fastText 训练参数的速查对照表,把”每个旋钮拧了会发生什么、默认值多少、什么时候该拧”摊平在一页里,是《理解 FastText 原理》那份课件的”末页操作手册”。
一、这份材料解决什么问题
上一份材料《【理解】FastText 原理》讲的是”为什么快、为什么对中文有效”,词袋、char n-gram、哈希桶、词向量平均。但真正把模型跑起来、把指标提上去的,是调参。原理课件第 5 页自己也承认:”工作中可能需要花很多时间在参数调整上面,就是不断试错,这也是’调参工程师”炼丹’的来源。”
这张表就是那次”试错”的弹药清单。它回答三个问题:
- 有哪些旋钮?25 个参数,从数据路径到日志级别全覆盖。
- 默认值是多少?
lr=0.1、dim=100、epoch=5、wordNgrams=1、loss=softmax……这是”不动任何东西”的基线。 - 什么时候该拧?每个参数都给了”小数据集用 X、大数据集用 Y”的分档建议,这就是省掉大量盲试的经验值。
在新闻分类项目流水线里,它的位置非常具体:流水线第二级 FastText 就靠这张表调出成绩,用来证明”传统算法 + 浅层模型”能到什么水平,从而给后面 BERT、LLM 的对比留出参照系。表里 autotuneValidationFile 一族的参数,更是项目里那 1 万条验证集的直接用途,有验证集就能自动搜索超参,不用手搓网格。
二、核心结论
- 真正”必须”的只有
input。表中是否必须列写”必须(有默认)”,语义是”这是参数项、但不是必填项”,24 个参数都有默认值,不写就是取默认。 - 先调顺序、后调数值。参数之间不是平等的:
lr/epoch决定”学没学会”,wordNgrams/minn+maxn决定”特征够不够”,dim/bucket决定”容量与内存”,loss决定”用不用近似”。乱序调参等于白烧算力。 minn/maxn是中文场景的开关,且默认是关的(默认 0 = 禁用子词)。不打开它,fastText 相对 TF-IDF 的优势会大打折扣。bucket是内存大户:2,000,000 桶 ×dim=100× 4 字节 ≈ 763 MiB,dim提到 300 就 ≈ 2.2 GiB。调dim之前先算这笔账。thread > 1会破坏可复现性。表中明说”如若想要复现结果,可以设置为 1″,谈起”多线程训练结果不稳定”时,这就是现成的答案。
三、知识地图
按”作用域”把 25 个参数分四组(保留表中原始层级,权重沿用原材料的【了解】定位):
【了解】fastText参数示例
├── A. 数据与词典(决定"喂什么进去")
│ ├── input 无默认,必须 训练数据文件路径,需分词 + 每行带标签
│ ├── label __label__ 标签前缀
│ ├── minCount 1 最小词频,过滤低频词
│ ├── minCountLabel 0 最小标签频次(不平衡数据可设 5-10)
│ ├── wordNgrams 1 词级 n-gram 长度(设 2 起步)
│ ├── minn 0 子词最小长度(中文建议 2-3)
│ ├── maxn 0 子词最大长度(建议与 minn 一起调)
│ ├── bucket 2000000 子词哈希桶数
│ ├── t 1e-4 高频词下采样阈值(ns 时有效)
│ └── pretrainedVectors 空 外部预训练词向量路径
├── B. 训练(决定"怎么学")
│ ├── lr 0.1 学习率
│ ├── lrUpdateRate 100 学习率更新频率
│ ├── dim 100 词向量维度
│ ├── ws 5 上下文窗口(分类任务作用有限)
│ ├── epoch 5 训练轮数
│ ├── loss softmax softmax / ns / hs / ova
│ ├── neg 5 负采样数量(ns 时有效)
│ ├── thread CPU 核心数-1 训练线程数
│ └── seed 0 随机种子
├── C. 诊断
│ └── verbose 2 日志详细程度(2 调试 / 0 静默 / 3 打印超参)
└── D. 自动调参(autotune,需提供验证集,否则全部无效)
├── autotuneValidationFile " " 验证数据路径(总开关)
├── autotuneMetric f1 优化指标
├── autotunePredictions 1 评估时预测标签数(top-k)
├── autotuneDuration 300 搜索时间上限(秒)
└── autotuneModelSize 空 模型体积上限(如 "2M")
记忆抓手:A 组改的是”输入的样子”,B 组改的是”学习的动力学”,D 组是”让机器替你调 A 和 B”。
四、原理详解
4.1 input 与 label:数据入口和标签语法
fastText 是监督分类器,它不需要人工构造特征,只要求每行是”标签 + 文本”。
input 指向训练文件路径,每行一条样本,格式为 __label__标签名 文本,文本需先分词(表中示例:__label__positive 很好 的 产品)。label 参数定义前缀字符串,默认 __label__;带这个前缀的 token 被解析为标签,其余 token 进入词袋。
新闻标题 10 分类的每一行
__label__体育 国足 客场 1比0 战胜 韩国 队
__label__科技 苹果 发布 M4 芯片 性能 提升 显著
注意:中文必须先分词(jieba 之类),因为 fastText 按空格切 token;不切就是一整行当成一个词,minn/maxn 的子词也救不回来。
易踩:标签名里不要带空格、也不要以空白开头;label 改了,预测结果的前缀也会跟着变,下游 strip_prefix 的解析逻辑要同步改。
4.2 lr:学习率,第一优先级旋钮
每次看完一条样本,模型往负梯度方向挪一步,lr 决定步子多大。步子太小 → 训不动;太大 → 在最优解附近来回横跳甚至发散。
fastText 用 SGD,并按训练进度把学习率从 lr 线性衰减到 0,所以训练日志里最后一行的 lr 常显示 0.000000,这是正常现象,不是参数没生效。lrUpdateRate(默认 100)控制”每处理多少个词更新一次学习率”这一节奏。
带数字的建议(表格原文分档):小数据集 0.01-0.05(更稳定),大数据 0.1-0.5(更快收敛),建议从 0.1 开始试。官方教程里还有一个对照实验:同一份数据把 epoch 从 5 提到 25,P@1 从 0.124 涨到 0.501;再把 lr 从 0.1 提到 1.0,P@1 涨到 0.563,说明 lr 和 epoch 是一对,单独调一个容易得出”这个参数没用”的错误结论。
本项目:18 万条训练数据按表格属于”大数据”,可从 lr=0.5 起,配 epoch=10。
4.3 dim:词向量维度,容量与内存的总闸门
每个词(和每个子词桶)用一个 dim 维实数向量表示。维度越高,能装的语义越丰富,也越容易记住噪声,同时显存/内存线性增长。
dim 同时决定嵌入矩阵的词维度与最终句子向量的维度。句子向量是所有 token 向量(词 + 子词 + wordNgram 哈希)的平均,所以 dim 也是分类全连接层的输入宽度。
表格分档:小数据集 10-50(防过拟合),大数据 100-300(强表达),建议从 100 调整。
内存账(自己算的,用来判断上限):子词桶矩阵大小 ≈ bucket × dim × 4 字节。
| bucket | dim | 仅子词矩阵占用 |
|---|---|---|
| 500,000 | 100 | ≈ 191 MiB |
| 2,000,000 | 100 | ≈ 763 MiB |
| 2,000,000 | 300 | ≈ 2.2 GiB |
所以”大数据 → dim 上 300″要和 bucket 一起看,两者是乘法关系,不是加法。
4.4 epoch:看几遍数据
一遍数据只够模型”初识”,epoch 就是重复阅读次数。
每个 epoch 会把训练集按快照方式完整过一遍(负采样与高频词下采样会改变实际参与更新的样本)。epoch 与 lr 共同决定”总学习步数 × 步长”这个总位移。
表格分档:小数据集 20-50(更充分),大数据 5-10(高效),建议根据验证集调整。这就是官方教程那个 5 → 25 的例子的意义:12k 条数据属于”小”,所以默认 5 轮远远不够。
本项目:18 万条属于大数据,epoch=5-10 已经能充分收敛;注意 fastText 的 epoch 上限被实现限制在 50 以内(设更大值以实际行为为准,建议不要依赖极端值)。
4.5 wordNgrams:把短语连成一个特征
单个词丢掉了顺序信息,”不 好看”和”好看”在词袋里几乎一样。词级 n-gram 把连续几个词拼成一个新 token,让模型直接看到短语。
wordNgrams=2 时,相邻两词组合成的二元组会作为额外特征进入词袋并哈希到桶里;=3 则再叠加三元组。这跟原理课件里那张”n=2 / n=3 组合”的示意图是同一件事,是在词的层面上组合,不是把词切成字(那是 minn/maxn 干的活)。
表格建议:默认 1(不用 n-gram);建议设 2 起步,3 适合复杂任务。注意 n-gram 会让特征数(和桶的占用)成倍增加,配合 bucket 一起调。
4.6 minCount / minCountLabel:把噪声关在门外
只出现一两次的词,学不出可靠向量,反而容易成为”记住这条样本”的捷径。
minCount 过滤词频低于阈值的词(它们不再有自己的向量,但如果开了 minn/maxn,仍可被子词覆盖);minCountLabel 同理过滤低频标签。
表格分档:minCount 小数据集设 1(保留更多词),大数据设 5-10(减噪声),建议从默认测试;minCountLabel 默认 0(保留所有标签),不平衡数据可设 5-10,多数场景无需调整。
重要提醒:一旦把 minCountLabel 设成 5,标签全部被过滤掉的样本就变成”无标签样本”,会被跳过,这是标签分布被悄悄改动,要回头确认训练集还剩多少条。
4.7 minn / maxn:中文场景的真正开关
一个词没见过,不代表它的片段没见过。char n-gram 让”智能手机”即使作为整词首次出现,也能借用”智能””手机”的向量。
minn/maxn 是字符级 n-gram 的最小/最大长度,作用在分词后的词内部。表格给的例子很直观:设 2-3 时”产品”分解为”<产””产品”(<、> 是词首尾边界符,用来区分”出现在词首”和”出现在词中”);设 4-6 时”智能手机”可分解为”智能””手机”这样的片段。
默认值陷阱:minn=0、maxn=0 表示禁用子词。中文语料词表爆炸、新词不断,关掉子词等于放弃 fastText 最核心的武器。表格明确建议:中文建议启用(2-3),并且 maxn 与 minn 一起调整,建议 minn=2、maxn=4。
代价:开子词后,每个词会生成多个片段,全部要哈希进 bucket,桶的占用和训练时间都会上升,这也是原理课件说”一句话就能产生很多不同片段”的另一面。
4.8 loss:损失函数,四选一
类别多的时候,标准 softmax 要为每个类别算一次归一化,代价随类别数线性上升。近似方法用”少算一些”换速度。
四种取值对比(表格原文 + 官方文档机制):
| 取值 | 机制 | 何时用(表格建议) |
|---|---|---|
softmax |
标准多分类,精确、概率可直接解释 | 小数据(< 10 万条),精确;单标签首选 |
ns(negative sampling) |
每个样本只更新正类 + neg 个随机负类,不算全类别归一化 |
大数据(> 10 万条),需配合 neg |
hs(hierarchical softmax) |
用霍夫曼树把 O(k) 的归一化降到 O(log k),逐节点做二分类 | 大数据;类别极多时优势明显,适合多标签 |
ova(one-vs-all) |
每类一个独立的二分类器 | 多标签任务 |
官方文档补充了两点关键机制:hs 建的是霍夫曼树,高频标签路径更短,所以平均查找更快;ova 场景下”降低学习率是个好主意”(多分类器之间会互相干扰)。另外官方把 ova 也写作 one-vs-all,两种写法等价。
本项目:10 个类别、单标签,softmax 的归一化开销只有 10 类,几乎可以忽略,不要因为”大数据”就盲目切到 ns,先用 softmax 拿到基线,再试 ns 看有没有提速收益。
4.9 neg 与 t:负采样的一对参数
ns 损失要”抽几个假类别当作反例”。抽太少学不准,抽太多变慢。
neg 是负样本数量;t 是高频词下采样阈值,只在 ns 下有效,高频词(”的””了”)被以一定概率丢弃,让训练重心落在信息量大的词上。表格建议:neg 默认 5 适合小数据,大数据设 10-20(更精准但更慢),建议测试 5-10;t 设 1e-5 到 1e-3,建议默认或测试 1e-5。
注意:这两个参数在 loss=softmax 或 hs 时不生效。看到”调了 neg 但指标没动”,先确认 loss 是不是 ns。
4.10 bucket:子词哈希桶数
子词片段数量理论上无穷(任何字符串组合),不可能给每个片段一个独立编号,于是用哈希把它们塞进固定数量的桶里。桶 = “子词的容量池”。
bucket 决定这个池子多大,与 dim 相乘得到子词矩阵的内存占用(见 4.3 的账)。表里建议:配合 minn/maxn 使用,小数据设 500000-1000000(省内存),大数据保持默认 2,000,000,视硬件调整。
冲突处理:桶不够时,不同子词哈希到同一桶,向量互相污染(哈希冲突);桶太大则内存吃紧。中文语料子词极多,不建议为了省内存把桶压得太小,宁可降 dim。
4.11 thread / seed:速度与可复现的对立
thread 是训练线程数(默认 CPU 核心数 – 1),多线程异步更新词向量以加速。表格建议设 8-16,视 CPU 核心数调整;”如若想要复现结果,可以设置为 1″。
为什么:多线程下各线程抢占更新同一批向量,更新顺序不确定,结果就不可复现。seed(默认 0)控制随机种子(负采样、下采样、初始化),但多线程下只设 seed 并不能保证可复现,必须 thread=1 + 固定 seed 双管齐下。被追问到这是一道很常见的”怎么保证实验可复现”的追问。
4.12 ws / lrUpdateRate / verbose / pretrainedVectors
ws(默认 5):上下文窗口。表格直说”分类任务作用有限,建议默认,无需调整,优先调wordNgrams“。原因:fastText 分类用的是词袋 + 向量平均,并不做真正的上下文依赖建模,ws主要影响需要上下文的 skipgram/cbow 训练。lrUpdateRate(默认 100):学习率更新频率,”控制参数更新节奏,默认即可,无需调整”。verbose(默认 2):日志级别。2 适合调试,0 静默运行,设 3 可打印超参数,查”我到底传进去什么参数了”时最有用的一招。pretrainedVectors(默认空):加载外部预训练词向量(.vec文本格式)来初始化词向量,”提升性能,无预训练向量无需设置”。注意:启用它是热启动,词表要对齐,且小数据集上收益才明显。
4.13 autotune 五件套:把调参交给机器
原理课件第 6 页讲了自动搜索的三步原理,判断参数重要性 → 确定调整方向 → 在好点附近精调并探索新区域(类似随机搜索 + 遗传算法)。fastText 把这套东西做成了内置功能。
总开关:只要给 autotuneValidationFile 一个验证集路径,自动调参就启动,其余四个参数才有意义;不提供验证集,这五个参数全部无效。
| 参数 | 默认 | 作用 |
|---|---|---|
autotuneValidationFile |
" " |
验证数据路径,总开关;提供验证集就省去手动调参 |
autotuneMetric |
f1 |
优化目标(如 f1、precision),配合验证集使用 |
autotunePredictions |
1 |
评估时预测标签数(k=3 即 top-3);多标签设 2-5,单标签默认 1 |
autotuneDuration |
300 |
搜索时间上限(秒);设 600-1800(10-30 分钟) 平衡性能与成本 |
autotuneModelSize |
空 | 模型体积上限(如 "2M"),移动端部署时用小模型约束搜索空间 |
机制补充:当指定了 autotuneModelSize,fastText 在搜索过程中会对候选模型做量化以满足体积约束(官方文档说明”空 = 不做量化”)。这正好接上项目后面”模型压缩”那一章,autotune 从第一天就在为压缩留后路。
本项目:那 1 万条验证集就是为它准备的。第一次上线可以用 autotuneDuration=1800 跑 30 分钟,让它自己找 lr/dim/wordNgrams 的组合,比自己猜要靠谱。
五、易错点与常见误解
常见说法:”表里写着’必须’,所以 25 个参数都要填。”
实际上,只有 input(以及输出路径)是真必填,其余 24 个都有默认值。
原因在于,表格的”是否必须”列写”必须(有默认)”,语义是”这是个正式参数项、但可以走默认”,跟 Python 的 train_supervised(input=...) 只给 input 就能跑是一致的。
有人以为”epoch 设大点总没错,设 500。”
其实小数据 20-50、大数据 5-10,按验证集定。
背后的道理是,轮数过多会记住训练集(过拟合),而且 fastText 的学习率是衰减到 0 的,后期步长趋近于零,多出来的轮数大多是白跑。
常听到的一种说法是:”minn/maxn 默认就是开启子词的。”
真实情况是,默认 0/0 是禁用,要显式设成比如 minn=2, maxn=4。
之所以如此,中文语料下不启用子词,未登录词只能退化成 <unk> 一类,fastText 相对 TF-IDF 的核心优势直接消失。
容易想岔的地方:”调了 neg 没效果,这个参数是不是坏了。”
事实正相反,neg 只在 loss=ns 下生效;t 同理。
为什么:softmax / hs 不走负采样路径,参数被读取但不参与计算。
先说一个误解:”我把 seed 固定成 42 了,结果应该能完全复现。”
实际上,还要同时 thread=1;表格明确写了这一点。
原因在于,多线程异步更新导致浮点累加顺序不同,种子的确定性被并行顺序的随机性覆盖。
常见说法:”中文句子直接扔进 input 就行。”
其实必须先分词,每行 __label__标签 词1 词2 ...。
背后的道理是,fastText 以空格切 token;中文不分词,整句会变成一个”词”,wordNgrams 与 minn/maxn 都无从谈起。
有人以为”类别只有 10 个,直接上 hs/ns 更快。”
真实情况是,10 类时 softmax 归一化开销极小,先拿精确基线。
之所以如此,表格的”大数据用 ns/hs”是针对类别规模大的场景;类别数少时近似方法省不下多少时间,却损失了可直接解释的概率。
常听到的一种说法是:”验证集是给我自己看指标的,跟训练无关。”
事实正相反,有了 autotuneValidationFile,验证集会参与超参搜索。
为什么:这是 autotune* 五件套的唯一入口;但同时也要意识到,反复用同一份验证集做自动搜索,会让验证集逐渐”被看过”,最终测试集才是干净的裁判。
六、横向对比与研究脉络
6.1 loss 四种取值的横向对比
| 维度 | softmax | ns | hs | ova |
|---|---|---|---|---|
| 原理 | 全类别归一化,精确多分类 | 正类 + neg 个随机负类 |
霍夫曼树逐节点二分类,O(log k) | 每类独立二分类器 |
| 优点 | 概率精确、可直接解释 | 类别多时快 | 类别多时快,树按频次优化路径 | 天然支持多标签 |
| 缺点 | 类别多时慢 | 负采样带来估计偏差,需调 neg/t |
多标签下需额外处理 | k 个分类器,训练更贵 |
| 适用场景 | 类别少(含本项目 10 类) | 大数据、类别多 | 大数据、类别极多 | 多标签 |
| 配套参数 | dim、epoch |
neg、t |
无(树自动构建) | 建议降低 lr |
| 复杂度感受 | O(k)/样本 | ≈ O(neg)/样本 | ≈ O(log k)/样本 | O(k)/样本 |
6.2 特征侧三兄弟的分工
| 参数 | 作用层级 | 解决什么 | 本项目建议 |
|---|---|---|---|
wordNgrams |
词与词之间 | 短语、搭配、否定词顺序 | 2 起步,复杂任务试 3 |
minn/maxn |
词内部(字符级) | 未登录词、词形变化、中文新词 | minn=2, maxn=4 |
bucket |
两者共用的存储 | 给上面两类碎片提供容量 | 默认 2,000,000,或降到 1,000,000 |
6.3 脉络:谁解决了谁的什么问题
- 词袋 + 线性分类器:快,但没有顺序、没有未登录词能力、需要人工特征工程。
- wordNgrams(词级组合):用极低代价补回局部顺序信息 → 表格”设 2 起步”。
- char n-gram(minn/maxn)+ 哈希桶:用子词共享解决未登录词 / 稀疏问题,桶数
bucket让存储可控 → 表格”中文建议启用(2-3)”。 - 近似损失(ns / hs):把类别数从”精度瓶颈”变成”效率瓶颈”再解决掉 → 表格”大数据试 ns,hs 适合多标签”。官方文档补充了
hs用霍夫曼树让高频类路径更短这层优化。 - autotune:把上面这些相互纠缠的旋钮交给自动搜索 → 表格的”提供验证集省去手动调参”,其原理正是原理课件第 6 页那三步。
七、在新闻分类项目中的落地
在流水线中的位置:第二级模型,承接 TF-IDF + 随机森林 基线,用极小的时间成本给出”浅层神经网络 + 词向量”的成绩,作为 BERT 微调的对照组。
数据形态:训练 18 万 / 测试 1 万 / 验证 1 万,标题\t标签 格式,需要转换成 fastText 要求的 __label__标签 分词后的标题。
7.1 「新闻标题 10 分类」推荐起始参数
18 万条属于表格里的”大数据”档,10 个类别属于”类别少”,所以起始点这样取:
import fasttext
model = fasttext.train_supervised(
input="train_ft.txt", # __label__体育 国足 客场 战胜 韩国 队
lr=0.5, # 大数据档 0.1-0.5;从 0.5 起,配 epoch=10
dim=100, # 表格建议从 100 起,先别冲 300
epoch=10, # 大数据档 5-10
wordNgrams=2, # 表格建议 2 起步
minCount=5, # 大数据档 5-10,减噪声
minCountLabel=0, # 10 类分布尚可,保留所有标签
minn=2, maxn=4, # 中文必须开子词
bucket=2000000, # 先保持默认,跑通再看内存
loss="softmax", # 10 类单标签,精确优先
thread=8, # 表格建议 8-16
seed=42, # 配合 thread=1 才能严格复现
verbose=2,
)
n, p, r = model.test("valid_ft.txt") # 返回 (样本数, 精确率, 召回率)
model.save_model("fasttext_news.bin")
规模心里有数:18 万条 × 约 12 词 ≈ 216 万词/轮,epoch=10 约 2160 万词的处理量,配 thread=8 在 CPU 上是分钟级的事。而 bucket=2,000,000 × dim=100 的子词矩阵约 763 MiB,先确认机器扛得住再往上调 dim。
7.2 调参顺序(按表格建议整理成流水线)
| 阶段 | 调什么 | 依据(表格原文) | 判定标准 |
|---|---|---|---|
| 0 | 数据质量:jieba 分词、去停用词(复用那 749 个停用词)、标签清洗 | input 需分词、每行带标签 |
词表规模、类别分布 |
| 1 | 收敛矛盾:lr + epoch |
大数据 lr 0.1-0.5、epoch 5-10 |
验证集 F1 是否还在涨 |
| 2 | 特征矛盾:wordNgrams |
“设 2 起步,3 适合复杂任务” | 短语类标题收益 |
| 3 | 泛化矛盾:minn/maxn(必开)→ minCount |
“中文建议启用(2-3)””大数据设 5-10” | 未登录词比例、噪声词数量 |
| 4 | 容量矛盾:dim |
“大数据 100-300” | 配合内存账,2.2 GiB 是 dim=300 的代价 |
| 5 | 效率矛盾:loss 试 ns(配 neg、t) |
“> 10 万条用 ns/hs” | 速度提升是否值得精度损失 |
| 6 | 兜底:autotuneValidationFile 交给机器 |
“autotuneDuration 设 600-1800” | 用 1 万验证集,30 分钟换一轮最优组合 |
这套顺序的设计原则(来自原理课件的”主要矛盾”说法):不可能所有参数同时最优,先解决对目标影响最大的(收敛),再转向下一组矛盾(特征 → 泛化 → 容量 → 效率)。跳步调参等于在噪声里找信号。
7.3 实际坑
- 格式转换错一次就白训:标签前缀必须和
label默认值一致;标题\t标签要翻成__label__标签 标题,且标题要先分词。 test()返回三元组:(样本数, 精确率, 召回率),别把第一个数当成准确率去报成绩。- 单线程复现:要交”可复现的实验报告”时,
thread=1+ 固定seed,否则同样的代码两次结果对不上。 - 验证集双重用途:既用来早停/选参,又用
autotune搜参,容易过拟合验证集。最终成绩以测试集的 1 万条为准。 verbose=3是排查利器:怀疑参数没生效(比如neg在softmax下无效),先打印一遍真实超参。
7.4 与项目其它方案怎么配合
| 环节 | 与 FastText 的关系 |
|---|---|
| TF-IDF + 随机森林 | 前置基线。两者的共同上游都是那 749 个停用词与分词结果,同一份分词产物喂两个模型,对比才公平 |
| BERT 微调 | 后置强模型。FastText 的分数是”性价比锚点”:若 BERT 只涨一点却慢几十倍,本身就是可讲的结论 |
| LLM(DeepSeek 零样本/少样本) | 不做训练,做兜底与增强。FastText 训练成本极低,适合当”标注质检”或”LLM 结果的快速对照” |
| 模型压缩 | autotuneModelSize(如 "2M")就是为移动端部署准备的入口;量化里的 -cutoff/-retrain 同样服务于压缩。调参时就把体积约束带上,后面少一轮返工 |
| Flask + Streamlit | save_model() 出的 .bin 直接被 Flask 加载,predict(k=3) 返回 top-3 给前端展示 |
八、重点问答
Q1:fastText 调参你先调哪个,为什么?
A:我先调 lr 和 epoch,因为这两个是”学没学会”的总开关。fastText 默认 lr=0.1、epoch=5,在数据量不大的时候严重欠拟合,官方教程里光把 epoch 从 5 提到 25,P@1 就从 0.124 涨到 0.501。我的习惯是大数据 lr=0.5、epoch=10 起手,然后看验证集 F1 有没有到平台期。等收敛稳住了,再动特征侧的 wordNgrams、minn/maxn,最后才是容量侧的 dim 和效率侧的 loss。
Q2:minn/maxn 默认是 0,这对中文意味着什么?
A:意味着子词默认是关掉的,得显式打开。它们是字符级 n-gram 的长度范围,作用在分词后的词内部:设 minn=2, maxn=4,”产品”能拆成”<产””产品”这类片段。中文新词多、词表爆炸,不打开子词的话,没见过的词基本没有有效向量,fastText 相对 TF-IDF 的核心优势就用不上了。所以我做中文分类一定会带上这两个参数,代价是桶的占用和训练时间会上升。
Q3:loss 有 softmax、ns、hs、ova,你怎么选?
A:我看两个维度,类别数和是否多标签。类别少、单标签就用默认的 softmax,概率精确、可解释,归一化开销也就 k 类,10 类时几乎可以忽略。类别到十万量级再考虑 ns 或 hs:ns 每个样本只更新正类和 neg 个负类,要配 neg 和 t 一起调;hs 用霍夫曼树把归一化从 O(k) 降到 O(log k),高频类路径更短,类别极多时优势明显。多标签就直接上 ova,每类一个独立二分类器,官方建议这种情况把学习率降一点。
Q4:多线程训练为什么结果不可复现?怎么解决?
A:fastText 的 thread 默认是 CPU 核心数减 1,多线程是异步更新同一批词向量的,更新顺序不确定,浮点累加的顺序也不一样,结果自然漂。光固定 seed 不够,因为种子管的是随机采样,管不住并行顺序。要严格复现就 thread=1 再配固定 seed,这两个得一起用。做正式实验报告我会单线程跑,平时探索阶段才开 8 到 16 线程提速。
Q5:bucket 和 dim 有什么关系?
A:它们是乘法关系,共同决定子词矩阵的内存。子词片段数量理论上无穷,靠哈希塞进固定数量的桶里,bucket 是桶数、dim 是每个桶的向量维度,占用量约等于 bucket × dim × 4 字节。默认 bucket=2000000、dim=100 大概是 763 MiB,dim 上到 300 就变成 2.2 GiB 左右。所以想省内存我优先降 dim 或把桶设到 50 万到 100 万,但中文子词多,桶压太小会哈希冲突、向量互相污染,得不偿失。
Q6:你有 1 万条验证集,怎么用它少调点参?
A:直接用 fastText 的 autotune。给 autotuneValidationFile 指定验证集路径,自动调参就启动了,它会自己搜 lr、dim、wordNgrams 这些组合。我再配 autotuneMetric=f1 定目标,autotuneDuration=600 到 1800 给 10 到 30 分钟的预算,单标签 autotunePredictions 保持 1。如果目标是移动端,我还会加 autotuneModelSize="2M" 限制模型体积,它在搜索时顺便做量化。要留意的是,反复用同一份验证集搜索会让验证集逐渐”被看过”,最终成绩我还是以测试集为准。
Q7:ws 在分类任务里重要吗?
A:不太重要,这点表格里写得很直白,”分类任务作用有限,建议默认 5,优先调 wordNgrams“。原因是 fastText 分类走的是词袋加向量平均,并不真正建模上下文依赖,ws 主要影响 skipgram/cbow 学词向量的过程。所以做分类我基本不动 ws,把预算花在 wordNgrams 上,同样的算力换来的短语特征收益更大。
Q8:你的 FastText 基线跑出来一般什么水平,它的意义是什么?
A:它的绝对分数不是重点,重点是性价比锚点。它用分钟级的 CPU 训练、几十到几百兆的模型,就能给出一个有竞争力的分数,那我在简历和被追问时就能说:BERT 相比它涨了多少、代价是几十倍的训练时间,这个取舍结论是有数据支撑的。而且它的超参、数据格式、分词流程和后面的模型是复用的,等于顺手把流水线的数据管道验证了一遍。
九、延伸阅读
- 官方参数列表(本表的权威对照):https://fasttext.cc/docs/en/options.html
- 官方文本分类教程(含
epoch5→25、lr0.1→1.0 的实测对比与hs/ova讲解):https://fasttext.cc/docs/en/supervised-tutorial.html - 官方词向量教程(
minn/maxn、bucket的学习式用法):https://fasttext.cc/docs/en/unsupervised-tutorial.html - 官方速查表:https://fasttext.cc/docs/en/cheatsheet.html
- 源码与 Releases:https://github.com/facebookresearch/fastText
- 论文:Bag of Tricks for Efficient Text Classification(Joulin 等)https://arxiv.org/abs/1607.01759;Enriching Word Vectors with Subword Information(Bojanowski 等,子词 minn/maxn 的来源)https://arxiv.org/abs/1607.04606
- 中文分词工具:jieba https://github.com/fxsjy/jieba
- 同目录兄弟材料:
【理解】FastText原理.原文.md(词袋 / char n-gram / 哈希桶的原理,以及”自动调参三步原理”)
附录:fastText 参数完整对照表
| 参数名 | 默认值 | 是否必须 | 备注 |
|---|---|---|---|
| input | 无 | 必须(无默认) | 训练数据文件路径,需分词(如“词 1 词 2”),每行带标签(如“__label__positive 很好 的 产品”)。 |
| lr | 0.1 | 必须(有默认) | 学习率,控制训练速度。小数据集用 0.01-0.05(更稳定),大数据用 0.1-0.5(更快收敛)。建议从 0.1 测试。 |
| dim | 100 | 必须(有默认) | 词向量维度,决定模型容量。小数据集用 10-50(防过拟合),大数据用 100-300(强表达)。建议从 100 调整。 |
| ws | 5 | 必须(有默认) | 上下文窗口大小,分类任务作用有限。建议默认(5),无需调整,优先调 wordNgrams。 |
| epoch | 5 | 必须(有默认) | 训练轮数,控制学习充分性。小数据集用 20-50(更充分),大数据用 5-10(高效)。建议根据验证集调整。 |
| minCount | 1 | 必须(有默认) | 最小词频,过滤低频词。小数据集设 1(保留更多词),大数据设 5-10(减噪声)。建议从默认测试。 |
| minCountLabel | 0 | 必须(有默认) | 最小标签频次,过滤低频标签。默认 0(保留所有标签),不平衡数据可设 5-10。多数场景无需调整。 |
| minn | 0 | 必须(有默认) | 子词最小长度,捕捉词内语义。设 2-3(如“产品”分解为“<产”“产品”),默认 0(禁用子词)。中文建议启用(2-3),处理未见词。 |
| maxn | 0 | 必须(有默认) | 子词最大长度,与 minn 配合。设 4-6(如“智能手机”分解为“智能”“手机”)。建议与 minn 一起调整(如 minn=2 maxn=4)。 |
| neg | 5 | 必须(有默认) | 负采样数量,影响 ns 损失效率。默认 5 适合小数据,大数据设 10-20(更精准但更慢)。建议测试 5-10。 |
| wordNgrams | 1 | 必须(有默认) | 词级 n-gram 长度,捕捉短语特征。设 2(如“很好 的”)提升分类性能,3 适合复杂任务。建议设 2 起步。 |
| loss | softmax | 必须(有默认) | 损失函数,影响训练效率。softmax 适合小数据(<10 万条,精确),ns/hs 适合大数据(>10 万条,高效,ns 需配合 neg,hs 适合多标签)。ova 用于多标签任务。建议小数据用 softmax,大数据试 ns,多标签用 ova(One-vs-All)。 |
| bucket | 2000000 | 必须(有默认) | 子词哈希桶数,控制子词存储容量。配合 minn/maxn,小数据设 500000-1000000(节省内存),大数据保持默认。视硬件调整。 |
| thread | CPU 核心数-1 | 必须(有默认) | 训练线程数,加速训练。建议设 8-16,视 CPU 核心数调整。如若想要复现结果,可以设置为 1 |
| lrUpdateRate | 100 | 必须(有默认) | 学习率更新频率,控制参数更新节奏。默认即可,无需调整。 |
| t | 1e-4 | 必须(有默认) | 负采样阈值,控制高频词采样(ns 损失时有效)。设 1e-5 到 1e-3,建议默认或测试 1e-5。 |
| label | label | 必须(有默认) | 标签前缀,标识标签格式。默认适用,无需调整。 |
| verbose | 2 | 必须(有默认) | 日志详细程度。2 适合调试,0 静默运行。设 3 可打印超参数。 |
| pretrainedVectors | 必须(有默认) | 预训练词向量路径,提升性能。无预训练向量无需设置。 | |
| seed | 0 | 必须(有默认) | 随机种子,确保可重复性。无需严格重复性可忽略。 |
| autotuneValidationFile | ” “ | 必须(有默认) | 验证数据路径,用于自动调优超参数(如 lr、dim)。提供验证集省去手动调参。无验证集无需设置。 |
| autotuneMetric | f1 | 必须(有默认) | 自动调优优化指标(如 f1、precision)。需配合 autotuneValidationFile,无验证集无效。 |
| autotunePredictions | 1 | 必须(有默认) | 自动调优时预测标签数(如 k=3 返回 top-3 标签)。多标签任务设 2-5,单标签默认 1。无验证集无效。 |
| autotuneDuration | 300 | 必须(有默认) | 自动调优时间(秒)。设 600-1800(10-30 分钟)平衡性能和成本。无验证集无效。 |
| autotuneModelSize | 必须(有默认) | 自动调优时模型大小限制(如“2M”)。适合移动端部署。无验证集无效。 |
表中共 25 行参数(
input为唯一无默认值的必填项)。