Instructions to use ModerRAS/AniFileBERT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use ModerRAS/AniFileBERT with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("token-classification", model="ModerRAS/AniFileBERT")# Load model directly from transformers import AutoTokenizer, AutoModelForTokenClassification tokenizer = AutoTokenizer.from_pretrained("ModerRAS/AniFileBERT") model = AutoModelForTokenClassification.from_pretrained("ModerRAS/AniFileBERT") - Notebooks
- Google Colab
- Kaggle
Anime Filename Parser Diagnostics Report
根因分析
当前症状不是 learning rate 问题,而是训练、验证、推理没有在同一个结构化输入空间里工作。
最高优先级根因是 tokenizer/data 配置错位:你给出的训练命令使用 dmhy_weak_char.jsonl 和 vocab.char.json,但没有传 --tokenizer char。旧版 train.py 默认 regex,因此 char 数据会被当作 regex 训练配置保存,checkpoint metadata 会写成 tokenizer_variant=regex。推理时 load_tokenizer() 按 checkpoint metadata 重新加载 regex tokenizer,于是 [LoliHouse] 这类结构 token 会作为一个整体进入模型,而 char 训练数据里它是 [, L, o, ..., ]。这会直接导致 group/title 边界漂移。
第二个根因是 word-level 数据和当前 AnimeTokenizer 也不完全一致。dmhy_weak.jsonl 里示例 token 是 [, LoliHouse, ],但当前 regex tokenizer 对原始文件名会输出 [LoliHouse]。这说明 word-level 数据名义上是 regex,但不是严格由当前 inference tokenizer 重放得到的 token 序列。
第三个根因是 char 训练命令没有设置 --max-seq-length 128。在抽样 5,000 条 char 数据中,默认 64 长度会截断 2,058 条,占 41.16%。episode/source/resolution 往往在后半段,默认长度会让模型训练和推理都丢失结构锚点。
第四个根因是评估指标误导。低 validation loss 和 token accuracy 会被大量 O、I-TITLE 稀释;真实任务需要 entity-level F1、字段 exact match,以及结构案例回归。
问题优先级
P0: 训练命令必须显式或自动使用 char tokenizer。已修改 train.py,现在会从数据集 metadata 自动识别 char,并把 char 默认 max length 提升到 128。
P0: 不允许 tokenizer variant 与 dataset metadata 不一致。已修改 train.py,检测到 dataset tokenizer_variant 与选择的 tokenizer 不一致会报错。
P0: 推理必须使用 checkpoint 保存的 tokenizer 和 max length。已修改 inference.py,默认读取 model.config.max_seq_length,并新增 --debug 输出 token/label/score/UNK/截断信息。
P1: 从旧 checkpoint fine-tune 到不同 vocab 时,不能按 ID 盲目 resize_token_embeddings()。已修改为按 token 字符串重映射 embedding,未匹配 token 再随机初始化。
P1: 数据集存在 BIO/边界质量问题。char 抽样 5,000 条发现 468 个 ORPHAN_I,典型是标题被括号 O 打断后仍继续 I-TITLE。B-X -> O 本身是合法 BIO,但在 group/title/source 频繁出现时是边界告警。
P2: 当前 BertForTokenClassification 独立逐 token 解码,不能约束非法转移。建议后续加 CRF 或 constrained BIO decoder。
自动诊断结果
新增脚本:
python diagnose_pipeline.py --data-file datasets/AnimeName/dmhy_weak_char.jsonl --vocab-file datasets/AnimeName/vocab.char.json --model-dir checkpoints/dmhy-finetune/final --sample-limit 5000 --eval-limit 128 --output diagnostics_report.md
char 数据抽样结果:
- tokenizer variant:
char - vocab size: 6,199
- UNK rate: 0.0000%
- O-label ratio: 37.47%
- p95 length: 101, p99 length: 125
- default max length 64 truncation: 41.16%
ORPHAN_I: 468- regex checkpoint 直接评 char 数据时 entity F1: 0.0832
word 数据抽样结果保存在 diagnostics_report_word.md:
- tokenizer variant:
regex - vocab size: 8,000
- UNK rate: 6.9158%
- default max length 64 truncation: 0%
- 当前 regex checkpoint 在抽样 word 数据上 entity F1: 0.9549
- 但 model checkpoint vocab 是 3,000,诊断 vocab 是 8,000,继续 fine-tune 必须重映射 embedding
Tokenizer Split 示例
输入:
[LoliHouse] Yomi no Tsugai - 07 [WebRip 1080p HEVC-10bit AAC ASSx2]
char tokenizer:
[, L, o, l, i, H, o, u, s, e, ], , Y, o, m, i, , n, o, , T, s, u, g, a, i, , -, , 0, 7, ...
当前 regex tokenizer:
[LoliHouse], , Yomi, , no, , Tsugai, , -, , 07, , [WebRip 1080p HEVC-10bit AAC ASSx2]
这两个 token 序列不是同一个标注空间。char label 不能直接套到 regex token 上,regex 模型也不能在 char token 序列上解释 logits。
BIO 与边界问题
真实非法 BIO:
... ( O, K I-TITLE, a I-TITLE ...
示例:
[LoliHouse] Kanteishi (Kari) - 07 [WebRip 1080p HEVC-10bit AAC]
( 被标为 O,后面的 Kari 继续 I-TITLE,形成 O -> I-TITLE。这会让模型学习到标题可以跨越被标为非实体的括号,边界自然会漂。
结构边界告警:
[KissSub][Shunkashuutou Daikousha - Haru no Mai][06][1080P][GB][MP4]
KissSub 是 B-GROUP,右括号是 O,这是合法 BIO;但如果 tokenizer 在推理时把 [KissSub] 合成一个 token,模型就无法只给内部文字打 GROUP,只能把整个 bracket token 判成一个类别。
Confusion 分析
故意用 char 数据评估 regex checkpoint,entity F1 只有 0.0832。主要混淆:
O -> TITLE: 930SOURCE -> TITLE: 236EPISODE -> TITLE: 228GROUP -> TITLE: 86
这与实际症状一致:模型把结构锚点和 meta 区域吸进 title,group/title 边界混淆,episode 被 title 或 O 吞掉。
已修改的代码
train.py
--tokenizer默认从数据集 metadata/vocab 名称/样本结构自动推断。- char 数据默认
max_seq_length >= 128。 - dataset metadata 与 tokenizer 不一致会直接报错。
- fine-tune 到新 vocab 时按 token 字符串重映射 embedding,避免 token ID 语义错位。
- checkpoint 保存正确的
tokenizer_variant和max_seq_length。
inference.py
- 新增
--debug,输出 tokenizer variant、token IDs、labels、scores、UNK rate、truncation、entity spans。 - 默认使用 checkpoint
max_seq_length。 - 修正推理截断逻辑,保留
[SEP],与训练一致。 - 默认使用 constrained BIO Viterbi 解码,阻止
O -> I-X这类非法转移;可用--no-constrained-bio查看原始 greedy 输出。 - 新增 rule-assisted parsing,兜底修复高置信结构锚点:leading group bracket、
- 07、S01E07、resolution、source。 - 可用
--no-rule-assist关闭规则兜底,只看模型原始输出。
diagnose_pipeline.py
- 自动检查 token/label 长度。
- 输出 BIO 违规样本与边界告警。
- 输出 tokenizer split 示例。
- 输出 train/inference tokenizer 对比。
- 输出实体、label、空格 label、UNK、截断统计。
- 可选加载 checkpoint 做 confusion 和 seqeval entity-level F1。
修改后的 Pipeline
推荐 char-level pipeline:
python diagnose_pipeline.py ^
--data-file datasets/AnimeName/dmhy_weak_char.jsonl ^
--vocab-file datasets/AnimeName/vocab.char.json ^
--sample-limit 20000 ^
--output diagnostics_report.md
python train.py ^
--tokenizer char ^
--data-file datasets/AnimeName/dmhy_weak_char.jsonl ^
--vocab-file datasets/AnimeName/vocab.char.json ^
--save-dir checkpoints/dmhy-char ^
--epochs 10 ^
--batch-size 128 ^
--learning-rate 0.0003 ^
--warmup-steps 300 ^
--max-seq-length 128 ^
--seed 42
python inference.py ^
--model-dir checkpoints/dmhy-char/final ^
--debug ^
"[LoliHouse] Yomi no Tsugai - 07 [WebRip 1080p HEVC-10bit AAC ASSx2]"
如果继续使用 word/regex pipeline,必须先重新生成数据,使 sample["tokens"] == AnimeTokenizer.tokenize(sample["filename"]) 对绝大多数样本成立;否则验证集仍然是训练 token 空间,真实 inference 是另一个 token 空间。
最合理的 Tokenizer 方案
当前任务更适合 char-level 或 deterministic hybrid tokenizer,不适合通用 subword tokenizer。
char-level 优点:
- train/inference 最容易完全一致。
- 不会把
[LoliHouse]、[WebRip ...]这类结构块压成单 token。 - 对未知标题、组名、罗马音、中文、日文都没有 OOV。
- 更适合学习括号、空格、连字符、集数位置这些结构信号。
char-level 缺点:
- 序列更长,必须用
max_seq_length=128。 - 逐 token softmax 容易出现 BIO 非法转移,建议加 CRF。
word-level/regex 优点:
- 序列短,训练快。
- 当前已有 checkpoint 在同 token 空间验证集上 F1 较高。
word-level/regex 缺点:
- 如果 bracket protection 把整段合并,内部 label 无法表达。
- 数据生成 tokenizer 和 inference tokenizer 稍有不一致就会严重错位。
- OOV 对新番标题和组名仍然明显。
结论:短期用 char-level + rule-assisted parsing;中期改为 hybrid tokenizer:保留结构符号 [ ] ( ) - _ . space 为独立 token,英文数字连续串可作为片段但必须能映射回字符 offset,并在 label alignment 上以 offset 为准;长期加 BERT + CRF。
建议训练配置
首选:
python train.py --tokenizer char ^
--data-file datasets/AnimeName/dmhy_weak_char.jsonl ^
--vocab-file datasets/AnimeName/vocab.char.json ^
--save-dir checkpoints/dmhy-char ^
--epochs 10 --batch-size 128 ^
--learning-rate 0.0003 --warmup-steps 300 ^
--max-seq-length 128 --seed 42
不要从 regex checkpoint 直接当作同构模型继续训练 char;如果要迁移,当前代码会按 token 字符串 remap embedding,但多数 char token 与 regex token 共享有限,最好从头训练 char 模型或只迁移 encoder 非 embedding 层。
必须新增评估:
- entity-level F1 by field
- field exact match:
group/title/episode/resolution/source - full parse exact match
- episode recall
- boundary errors: group-title, title-episode, episode-meta
- inference debug sample set,固定 50-200 个真实文件名回归
真实案例分析
输入:
[LoliHouse] Yomi no Tsugai - 07 [WebRip 1080p HEVC-10bit AAC ASSx2]
旧 regex checkpoint 原始模型输出:
{
"entities": [
{"type": "TITLE", "text": "[LoliHouse] Yomi no Tsugai"},
{"type": "EPISODE", "text": "07"}
]
}
问题点:
[LoliHouse]被 tokenizer 合成一个 token。- 模型把该 token 判成
B-TITLE,无法只把内部LoliHouse判成GROUP。 Yomi和Tsugai在 3,000 vocab checkpoint 中是[UNK],但模型仍高置信输出I-TITLE,说明 loss/置信度不能代表字段正确性。
修改后带规则辅助的最终输出:
{
"group": "LoliHouse",
"title": "Yomi no Tsugai",
"episode": 7,
"source": "WebRip",
"resolution": "1080p"
}
这只是上线兜底;真正修复仍应训练一个 train/inference token 完全一致的 char 或 hybrid 模型。
架构建议
最推荐的重构路线:
BERT encoder + CRF:约束O -> I-X、B-X -> I-Y等非法/低质量转移。- char-level NER:保证 token-label alignment 不受 subword split 影响。
- rule-assisted parser:先抽取高置信结构锚点,再让模型负责模糊 title/group 边界。
- offset-based dataset:每条数据保存 raw filename、entity spans、tokens、offset_mapping、labels,训练时由 tokenizer 统一生成 labels。
当前代码已先实现“无训练 CRF”的 constrained BIO decoding,作为上线前的轻量保护。完整 BERT+CRF 仍建议作为下一阶段训练架构重构。
不要只优化 loss。这个任务的目标函数应更接近真实解析准确率:字段级 exact match + episode recall + title boundary F1。