--- license: apache-2.0 language: - zh tags: - bert - chinese - text2text-generation - spelling-correction pipeline_tag: fill-mask library_name: pytorch --- # BERTc-315M-CSC 中文拼写纠错。基于 [BERTc-315M](https://huggingface.co/Ismantic/BERTc-315M) 微调。 双头:cor 逐位置预测正确的字(权重与词嵌入绑定),det 判断该位置有没有错(focal loss)。**只做等长替换**,不处理多字少字。 ## 指标 | 指标 | 值 | |---|---| | 句级 F1 | 0.8388 | | 准确率 | 0.8472 | | 精确率 | 0.9461 | | 召回率 | 0.7534 | ## 训练 - 配方:10 epoch,batch 32,lr 3e-5,warmup 0.1,det_weight 0.3,纠错阈值 0.7,max_len 128 - 数据:SIGHAN 13/14/15 的 train + Wang271K,去重后 249,975 对 ## 用法 ```python from csc_model import BERTcForCSC model = BERTcForCSC.from_pretrained(".") print(model.correct("他平时喜欢锻练身体")) # 他平时喜欢锻炼身体 print(model.correct(["句子一", "句子二"])) # 也接列表 ``` ## 评测口径 指标在 **SIGHAN-15 官方 707 条**上测(`shibing624/pycorrector` 里 `pycorrector/data/sighan2015_test.tsv` 那一版)。注意 CTCDataset 里还有个 1100 条的 `sighan15_test.jsonl`,不是同一个东西。 判定是**整句**级:整句完全一致才算对,改对一半不给分。 ## 阈值 `correct(..., threshold=0.7)`:纠错置信度低于阈值就保留原字。调低提召回、 调高提精确率。0.7 是与 MacBERT4CSC 对齐的默认值,报告的指标都基于它。 ## 一个反直觉的行为 `correct()` **只用纠错头,不用检测头**。检测头是训练时的辅助信号,推理不参与。 所以会出现"模型知道这里有错、但选不出正确的字"的情况。比如「我今天很稿兴」, `稿` 位置的检测分是 0.98,但纠错头的 top-1 仍是 `稿` 本身(0.22), `高` 只排第 4(0.11)—— 这种时候**调低阈值没有任何用**,阈值只能否决改动, 不能凭空造出改动。 ## 依赖 只需要 **PyTorch** 和 **PieceTokenizer**,没有别的。 | | | |---|---| | 模型定义 | 目录内的 `model.py`(纯 torch,不 import transformers) | | 权重读取 | 目录内的 `checkpoint.py`(85 行 safetensors 读取,不需要 safetensors 库) | | 分词器 | PieceTokenizer,提供字级切分和词表 | ```bash pip install torch pip install git+https://github.com/Ismantic/PieceTokenizer ``` 目录是自包含的:进到目录里直接 `python example_*.py` 就能跑,不依赖目录外的 任何文件。 ## Tokenizer 字级 SentencePiece,`BERTc-Tokenizer.pt`,词表 12536(pad=12531,mask=12535)。**必须用 `dict="no"` 加载**(字模式,不挂分词词典)——挂了词典编码结果会跟训练时不一致,而且不报错。 ```bash pip install git+https://github.com/Ismantic/PieceTokenizer ``` ## 文件 | 文件 | 说明 | |---|---| | `model.safetensors` | 骨干 + 双头 | | `csc_model.py` | 推理入口 `BERTcForCSC` | | `model.py` | 骨干定义 | | `tokenizer.py` | 字级 tokenizer | | `example_correct.py` | 示例 | ## 许可 Apache-2.0。训练语料各自的许可见对应数据集卡。