Panhapich commited on
Commit
c6a0fc8
Β·
verified Β·
1 Parent(s): f48fc26

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +96 -74
README.md CHANGED
@@ -1,74 +1,96 @@
1
- ---
2
- license: other
3
- language:
4
- - km
5
- - en
6
- tags:
7
- - khmer
8
- - cambodia
9
- - sentencepiece
10
- - tokenizer
11
- - unigram
12
- - code-switching
13
- pretty_name: Khmer SentencePiece 8K
14
- ---
15
-
16
- # khmer-sp-8k
17
-
18
- A **SentencePiece unigram** tokenizer (vocab size 8000) for Khmer with code-switched
19
- English, trained on [`Panhapich/khmer-text-corpus`](https://huggingface.co/datasets/Panhapich/khmer-text-corpus). It is the
20
- **shared vocabulary** for OCR, ASR, and the diffusion decoder in the Khmer multimodal project.
21
-
22
- ## Files
23
-
24
- | File | Description |
25
- |---|---|
26
- | `khmer_sp.model` | SentencePiece model (load this) |
27
- | `khmer_sp.vocab` | Human-readable vocabulary with log-probabilities |
28
- | `tokenizer_info.json` | Machine-readable manifest: vocab size + special-token IDs + provenance |
29
-
30
- ## Special tokens
31
-
32
- | Token | ID | Role |
33
- |---|---|---|
34
- | `<PAD>` | 0 | Padding |
35
- | `<UNK>` | 1 | Unknown |
36
- | `<BOS>` | 2 | Begin of sequence |
37
- | `<EOS>` | 3 | End of sequence |
38
- | `<MASK>` | 4 | Diffusion/masked-LM corruption token (user-defined, never split) |
39
-
40
- `<MASK>` is a SentencePiece `user_defined_symbol`, so it is one atomic token and must not collapse
41
- onto `<UNK>`. The authoritative IDs are in `tokenizer_info.json`.
42
-
43
- ## Usage
44
-
45
- ```python
46
- from huggingface_hub import hf_hub_download
47
- import sentencepiece as spm
48
-
49
- model_path = hf_hub_download("Panhapich/khmer-sp-8k", "khmer_sp.model")
50
- sp = spm.SentencePieceProcessor(model_file=model_path)
51
-
52
- text = "αžαŸ’αž‰αž»αŸ†αž€αŸ†αž–αž»αž„αž”αŸ’αžšαžΎ AI model"
53
- ids = sp.encode(text, out_type=int)
54
- print(ids)
55
- print(sp.decode(ids))
56
-
57
- MASK = sp.piece_to_id("<MASK>")
58
- assert MASK not in (-1, sp.unk_id()) # <MASK> must be a real token
59
- ```
60
-
61
- ## Training details
62
-
63
- | Setting | Value |
64
- |---|---|
65
- | Algorithm | SentencePiece `unigram` |
66
- | Vocab size | 8000 |
67
- | Character coverage | 0.9995 |
68
- | Training subsample | up to 2,000,000 sentences (shuffled) |
69
- | Corpus | `Panhapich/khmer-text-corpus` (Khmer + organically code-switched English) |
70
-
71
- ## Licensing
72
-
73
- Trained on a corpus derived from third-party datasets; distribution terms follow that corpus.
74
- Confirm the upstream licenses and set the `license` field accordingly β€” `other` is a placeholder.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ language:
4
+ - km
5
+ - en
6
+ tags:
7
+ - khmer
8
+ - cambodia
9
+ - sentencepiece
10
+ - tokenizer
11
+ - unigram
12
+ - code-switching
13
+ pretty_name: Khmer SentencePiece 8K
14
+ ---
15
+
16
+ # khmer-sp-8k
17
+
18
+ A **SentencePiece unigram** tokenizer (vocab size 8000) for Khmer with code-switched
19
+ English, trained on [`Panhapich/khmer-text-corpus`](https://huggingface.co/datasets/Panhapich/khmer-text-corpus). It is the
20
+ **shared vocabulary** for OCR, ASR, and the diffusion decoder in the Khmer multimodal project.
21
+
22
+ ## The tokenizer is several files working together, not one
23
+
24
+ `khmer_sp.model` was trained on **word-segmented** text (via `khmer-nltk`), not raw Khmer β€”
25
+ this is what prevents SentencePiece from fusing multiple words into a single vocab token (e.g.
26
+ `αžαŸ’αž‰αž»αŸ†αž…αž„αŸ‹` = "I"+"want" collapsing into one piece). Glued English/Latin runs (e.g. `tryAImodel`)
27
+ are also decomposed via `wordninja`, guarded by a case-sensitive exception list so domain terms
28
+ (ACLEDA, Bakong, COVID-19, 5G, ...) aren't mangled. See `khmer_segmentation_sentencepiece_approach.md`
29
+ for the full root-cause writeup.
30
+
31
+ **This means `khmer_sp.model` must never be loaded with a bare `SentencePieceProcessor` for
32
+ encode/decode.** Always go through `khmer_segmentation.KhmerTokenizer`, which runs the same
33
+ segmentation pipeline used at training time:
34
+
35
+ ```python
36
+ from huggingface_hub import hf_hub_download
37
+ from khmer_segmentation import KhmerTokenizer
38
+
39
+ sp_model_path = hf_hub_download("Panhapich/khmer-sp-8k", "khmer_sp.model")
40
+ gazetteer_path = hf_hub_download("Panhapich/khmer-sp-8k", "gazetteer.json")
41
+ latin_path = hf_hub_download("Panhapich/khmer-sp-8k", "latin_exceptions.json")
42
+
43
+ tok = KhmerTokenizer(sp_model_path, gazetteer_path, latin_path)
44
+
45
+ text = "αžαŸ’αž‰αž»αŸ†αž€αŸ†αž–αž»αž„αž”αŸ’αžšαžΎ AI model"
46
+ ids = tok.encode(text)
47
+ print(ids)
48
+ print(tok.decode(ids))
49
+
50
+ MASK = tok.sp.piece_to_id("<MASK>")
51
+ assert MASK not in (-1, tok.sp.unk_id()) # <MASK> must be a real token
52
+ ```
53
+
54
+ Also download `khmer_segmentation.py` itself (`hf_hub_download("Panhapich/khmer-sp-8k", "khmer_segmentation.py")`)
55
+ and import it locally, or vendor it into your own project β€” it is a required part of the
56
+ tokenizer, not optional preprocessing.
57
+
58
+ ## Files
59
+
60
+ | File | Description |
61
+ |---|---|
62
+ | `khmer_sp.model` | SentencePiece model, trained on **word-segmented** text (load via `KhmerTokenizer`, not directly) |
63
+ | `khmer_sp.vocab` | Human-readable vocabulary with log-probabilities |
64
+ | `khmer_segmentation.py` | Required segmentation pipeline (gazetteer + non-Khmer masking + khmer-nltk + wordninja) |
65
+ | `gazetteer.json` | Khmer loanword/acronym list masked before segmentation so it isn't shattered mid-word |
66
+ | `latin_exceptions.json` | English/Latin domain terms protected from `wordninja`'s glued-word decomposition |
67
+ | `tokenizer_info.json` | Machine-readable manifest: vocab size + special-token IDs + provenance |
68
+
69
+ ## Special tokens
70
+
71
+ | Token | ID | Role |
72
+ |---|---|---|
73
+ | `<PAD>` | 0 | Padding |
74
+ | `<UNK>` | 1 | Unknown |
75
+ | `<BOS>` | 2 | Begin of sequence |
76
+ | `<EOS>` | 3 | End of sequence |
77
+ | `<MASK>` | 4 | Diffusion/masked-LM corruption token (user-defined, never split) |
78
+
79
+ `<MASK>` is a SentencePiece `user_defined_symbol`, so it is one atomic token and must not collapse
80
+ onto `<UNK>`. The authoritative IDs are in `tokenizer_info.json`.
81
+
82
+ ## Training details
83
+
84
+ | Setting | Value |
85
+ |---|---|
86
+ | Algorithm | SentencePiece `unigram` |
87
+ | Vocab size | 8000 |
88
+ | Character coverage | 0.9998 |
89
+ | Pre-segmentation | khmer-nltk word tokenization + gazetteer/non-Khmer masking + wordninja Latin decomposition (required at inference too) |
90
+ | Training subsample | up to 2,000,000 sentences (shuffled) |
91
+ | Corpus | `Panhapich/khmer-text-corpus` (Khmer + organically code-switched English) |
92
+
93
+ ## Licensing
94
+
95
+ Trained on a corpus derived from third-party datasets; distribution terms follow that corpus.
96
+ Confirm the upstream licenses and set the `license` field accordingly β€” `other` is a placeholder.