tf-bao commited on
Commit
89aaa01
·
verified ·
1 Parent(s): d975ed6

Upload BERTc-165M-CSC

Browse files
Files changed (3) hide show
  1. BERTc-Tokenizer.pt +3 -0
  2. README.md +20 -2
  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
@@ -34,17 +34,35 @@ library_name: pytorch
34
  from csc_model import BERTcForCSC
35
 
36
  model = BERTcForCSC.from_pretrained(".")
37
- print(model.correct("我今天很稿兴")) # 我今天很高兴
 
38
  ```
39
 
 
 
 
 
 
 
 
 
40
  ## 阈值
41
 
42
  `correct(..., threshold=0.7)`:纠错置信度低于阈值就保留原字。调低提召回、
43
  调高提精确率。0.7 是与 MacBERT4CSC 对齐的默认值,报告的指标都基于它。
44
 
 
 
 
 
 
 
 
 
 
45
  ## Tokenizer
46
 
47
- 字级 SentencePiece,词表 12536(pad=12531,mask=12535)。**必须用 `dict="no"`
48
  加载**(字模式,不挂分词词典)——挂了词典编码结果会跟训练时不一致,而且不报错。
49
 
50
  ```bash
 
34
  from csc_model import BERTcForCSC
35
 
36
  model = BERTcForCSC.from_pretrained(".")
37
+ print(model.correct("他平时喜欢锻练身体")) # 他平时喜欢锻炼身体
38
+ print(model.correct(["句子一", "句子二"])) # 也接列表
39
  ```
40
 
41
+ ## 评测口径
42
+
43
+ 指标在 **SIGHAN-15 官方 707 条**上测(`shibing624/pycorrector` 里
44
+ `pycorrector/data/sighan2015_test.tsv` 那一版)。注意 CTCDataset 里还有个
45
+ 1100 条的 `sighan15_test.jsonl`,不是同一个东西。
46
+
47
+ 判定是**整句**级:整句完全一致才算对,改对一半不给分。
48
+
49
  ## 阈值
50
 
51
  `correct(..., threshold=0.7)`:纠错置信度低于阈值就保留原字。调低提召回、
52
  调高提精确率。0.7 是与 MacBERT4CSC 对齐的默认值,报告的指标都基于它。
53
 
54
+ ## 一个反直觉的行为
55
+
56
+ `correct()` **只用纠错头,不用检测头**。检测头是训练时的辅助信号,推理不参与。
57
+
58
+ 所以会出现"模型知道这里有错、但选不出正确的字"的情况。比如「我今天很稿兴」,
59
+ `稿` 位置的检测分是 0.98,但纠错头的 top-1 仍是 `稿` 本身(0.22),
60
+ `高` 只排第 4(0.11)—— 这种时候**调低阈值没有任何用**,阈值只能否决改动,
61
+ 不能凭空造出改动。
62
+
63
  ## Tokenizer
64
 
65
+ 字级 SentencePiece,`BERTc-Tokenizer.pt`,词表 12536(pad=12531,mask=12535)。**必须用 `dict="no"`
66
  加载**(字模式,不挂分词词典)——挂了词典编码结果会跟训练时不一致,而且不报错。
67
 
68
  ```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