tf-bao commited on
Commit
2772399
·
verified ·
1 Parent(s): 0584440

Upload BERTc-315M-CSC

Browse files
Files changed (3) hide show
  1. BERTc-Tokenizer.pt +3 -0
  2. README.md +21 -3
  3. tokenizer.py +8 -4
BERTc-Tokenizer.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8ecc3774ba1afc0225c22147e4ff719acfa1aa9df8616befcb6c12f730ac6e07
3
+ size 249668
README.md CHANGED
@@ -29,7 +29,7 @@ library_name: pytorch
29
  ## 训练
30
 
31
  - 配方:10 epoch,batch 32,lr 3e-5,warmup 0.1,det_weight 0.3,纠错阈值 0.7,max_len 128
32
- - 数据:SIGHAN + Wang271K + MCSCSet + CSCD-NS 等,去重后 826,097
33
 
34
  ## 用法
35
 
@@ -37,17 +37,35 @@ library_name: pytorch
37
  from csc_model import BERTcForCSC
38
 
39
  model = BERTcForCSC.from_pretrained(".")
40
- print(model.correct("我今天很稿兴")) # 我今天很高兴
 
41
  ```
42
 
 
 
 
 
 
 
 
 
43
  ## 阈值
44
 
45
  `correct(..., threshold=0.7)`:纠错置信度低于阈值就保留原字。调低提召回、
46
  调高提精确率。0.7 是与 MacBERT4CSC 对齐的默认值,报告的指标都基于它。
47
 
 
 
 
 
 
 
 
 
 
48
  ## Tokenizer
49
 
50
- 字级 SentencePiece,词表 12536(pad=12531,mask=12535)。**必须用 `dict="no"`
51
  加载**(字模式,不挂分词词典)——挂了词典编码结果会跟训练时不一致,而且不报错。
52
 
53
  ```bash
 
29
  ## 训练
30
 
31
  - 配方:10 epoch,batch 32,lr 3e-5,warmup 0.1,det_weight 0.3,纠错阈值 0.7,max_len 128
32
+ - 数据:SIGHAN 13/14/15 train + Wang271K,去重后 249,975
33
 
34
  ## 用法
35
 
 
37
  from csc_model import BERTcForCSC
38
 
39
  model = BERTcForCSC.from_pretrained(".")
40
+ print(model.correct("他平时喜欢锻练身体")) # 他平时喜欢锻炼身体
41
+ print(model.correct(["句子一", "句子二"])) # 也接列表
42
  ```
43
 
44
+ ## 评测口径
45
+
46
+ 指标在 **SIGHAN-15 官方 707 条**上测(`shibing624/pycorrector` 里
47
+ `pycorrector/data/sighan2015_test.tsv` 那一版)。注意 CTCDataset 里还有个
48
+ 1100 条的 `sighan15_test.jsonl`,不是同一个东西。
49
+
50
+ 判定是**整句**级:整句完全一致才算对,改对一半不给分。
51
+
52
  ## 阈值
53
 
54
  `correct(..., threshold=0.7)`:纠错置信度低于阈值就保留原字。调低提召回、
55
  调高提精确率。0.7 是与 MacBERT4CSC 对齐的默认值,报告的指标都基于它。
56
 
57
+ ## 一个反直觉的行为
58
+
59
+ `correct()` **只用纠错头,不用检测头**。检测头是训练时的辅助信号,推理不参与。
60
+
61
+ 所以会出现"模型知道这里有错、但选不出正确的字"的情况。比如「我今天很稿兴」,
62
+ `稿` 位置的检测分是 0.98,但纠错头的 top-1 仍是 `稿` 本身(0.22),
63
+ `高` 只排第 4(0.11)—— 这种时候**调低阈值没有任何用**,阈值只能否决改动,
64
+ 不能凭空造出改动。
65
+
66
  ## Tokenizer
67
 
68
+ 字级 SentencePiece,`BERTc-Tokenizer.pt`,词表 12536(pad=12531,mask=12535)。**必须用 `dict="no"`
69
  加载**(字模式,不挂分词词典)——挂了词典编码结果会跟训练时不一致,而且不报错。
70
 
71
  ```bash
tokenizer.py CHANGED
@@ -3,6 +3,9 @@
3
  这份代码会**随模型一起发到 HF**,所以只能依赖 piece_tokenizer 本身,
4
  不能 import 仓库里的任何东西。
5
 
 
 
 
6
  装 tokenizer:
7
  pip install git+https://github.com/Ismantic/PieceTokenizer
8
  """
@@ -18,16 +21,17 @@ class PieceCharTokenizer:
18
  训练时不一致,而且不会报错。
19
  """
20
 
 
 
21
  def __init__(self, model_dir="."):
22
  model_dir = Path(model_dir)
23
  self._tok = _pt.Tokenizer()
24
- self._tok.load(str(model_dir / "piece.model"), dict="no")
25
 
26
  self.pad_token_id = self._tok.piece_to_id("<pad>")
27
  self.unk_token_id = 0
28
- mask_path = model_dir / "mask_token_id.txt"
29
- self.mask_token_id = (int(mask_path.read_text().strip())
30
- if mask_path.exists() else self._tok.vocab_size())
31
  self.vocab_size = self._tok.vocab_size() + 1
32
  self._cache = {}
33
 
 
3
  这份代码会**随模型一起发到 HF**,所以只能依赖 piece_tokenizer 本身,
4
  不能 import 仓库里的任何东西。
5
 
6
+ 词表文件 BERTc-Tokenizer.pt 与 PieceTokenizer 仓库 save/ 下的那份逐字节相同 ——
7
+ 同名是为了让来源一目了然。
8
+
9
  装 tokenizer:
10
  pip install git+https://github.com/Ismantic/PieceTokenizer
11
  """
 
21
  训练时不一致,而且不会报错。
22
  """
23
 
24
+ MODEL_NAME = "BERTc-Tokenizer.pt"
25
+
26
  def __init__(self, model_dir="."):
27
  model_dir = Path(model_dir)
28
  self._tok = _pt.Tokenizer()
29
+ self._tok.load(str(model_dir / self.MODEL_NAME), dict="no")
30
 
31
  self.pad_token_id = self._tok.piece_to_id("<pad>")
32
  self.unk_token_id = 0
33
+ # [MASK] 追加在 piece 词表之后,id 就等于词表大小 —— 不需要单独存一个文件
34
+ self.mask_token_id = self._tok.vocab_size()
 
35
  self.vocab_size = self._tok.vocab_size() + 1
36
  self._cache = {}
37