Darayut commited on
Commit
5e91e8d
Β·
verified Β·
1 Parent(s): fbfc597

Update model card: new architecture, remove diffusion

Browse files
Files changed (1) hide show
  1. README.md +37 -18
README.md CHANGED
@@ -14,7 +14,18 @@ datasets:
14
  ---
15
 
16
  <div align="center">
17
- <img src="./assets/wordmark.png" width="50%" alt="Netra Lab" style="vertical-align: middle;"/>
 
 
 
 
 
 
 
 
 
 
 
18
  </div>
19
 
20
  <hr>
@@ -33,17 +44,17 @@ datasets:
33
  </h2>
34
 
35
  <p align="center">
36
- <img src="assets/inference_benchmark.png" style="width: 1000px" align=center>
37
  </p>
38
 
39
  <p align="center">
40
- <a href="">Inference Speed Benchmark on CPU Using Greedy, and Beam Search Decoding Strategy</a>
41
  </p>
42
 
43
  ## 1. Abstract
44
- This repository present Netra-NMT a 90M-parameter encoder-decoder transformer-based model trained on **220 million tokens** of English-Khmer parallel text (4.2M bidirectional examples). The encoder uses bidirectional self-attention, much like BERT, to capture global contextual representation. The decoder perform autoregressive generation through causal self-attention and encoder-decoder cross attention.
45
 
46
- Unlike traditional transformer block, Netra-NMT incorporates several architectural improvements, including Pre-Layer Normalization (Pre-LN) for stable optimization, SwiGLU feed-forward networks for enhanced representational capacity, and weight tying between the decoder embedding layer and output projection head to reduce parameter redundancy.
47
 
48
  ## 2. Dataset
49
 
@@ -66,45 +77,53 @@ Raw data was cleaned through the following pipeline:
66
  1. **Deduplication**: exact duplicate pairs removed across all sources.
67
  2. **Length filtering**: pairs with extreme source/target length mismatches were discarded.
68
  3. **Empty/null removal**: pairs where either side was empty or below a minimum token count were dropped.
 
 
69
 
70
  After cleaning, each surviving pair is duplicated in both directions (`ENβ†’KM` and `KMβ†’EN`) with a direction prefix token (`<2km>` / `<2en>`), yielding ~4.2 million training examples.
71
 
72
  ## 3. Model Architecture
73
 
74
  <div align="center">
75
- <img src="assets/model_architecture.png" width="70%" alt="Netra-NMT Architecture" />
76
  <p><em>Figure 1: Overview of the Netra-NMT encoder-decoder architecture. The encoder (left) processes the source sentence with bidirectional self-attention; the decoder (right) generates the target sentence autoregressively via causal self-attention and cross-attention over the encoder output. Both sides share a 32K SentencePiece tokenizer.</em></p>
77
  </div>
78
 
79
- Netra-NMT follows a standard encoder-decoder transformer architecture with several modifications for training stability and parameter efficiency.
80
 
81
- **Encoder** takes the source sentence tokenized by the shared 32K SentencePiece tokenizer, adds learned positional embeddings, and passes the sequence through 6 transformer layers with *bidirectional* self-attention (every token attends to every other token, similar to BERT). A final Pre-LN layer norm is applied to the encoder output before it is passed to the decoder via cross-attention.
82
 
83
- **Decoder** takes the (partially generated) target sentence through the same tokenizer, adds positional embeddings, and passes it through 6 transformer layers. Each decoder layer applies three sub-layers in order: (1) *causal* (masked) self-attention over previously generated tokens, (2) cross-attention over the full encoder output, and (3) a feed-forward block. A final Pre-LN layer norm feeds into the tied linear projection head to produce output token probabilities.
84
 
85
  **Architectural improvements over the vanilla transformer:**
86
 
87
  | Feature | Detail |
88
  |---------|--------|
89
- | Pre-Layer Normalization | Layer norm applied *before* each sub-layer (Pre-LN) rather than after, improving gradient flow and training stability |
90
- | SwiGLU FFN | Feed-forward blocks use the SwiGLU activation instead of ReLU, providing richer representational capacity at no parameter cost |
91
- | Weight tying | The decoder input embedding matrix is shared with the output linear projection head, reducing redundant parameters |
 
 
 
 
92
 
93
  **Hyperparameters:**
94
 
95
  | | |
96
  |---|---|
97
  | d_model | 512 |
98
- | Encoder / Decoder layers | 6 / 6 |
99
  | Attention heads | 8 |
100
  | FFN hidden size | 2048 |
101
- | Vocabulary | 32K (SentencePiece unigram, shared) |
102
- | Total parameters | ~89.7M |
 
 
103
 
104
  ## 4. Evaluation Results
105
 
106
  <p align="center">
107
- <img src="assets/metrics_benchmark.png" style="width: 1000px" align=center>
108
  </p>
109
 
110
  ## Install
@@ -133,7 +152,7 @@ under `~/.cache/huggingface`.
133
  from netra_nmt import NetraTranslator
134
 
135
  t = NetraTranslator() # auto-detect GPU/CPU; downloads weights once
136
- t.translate("Hello, how are you?", direction="en2km") # β†’ "αžŸαž½αžŸαŸ’αžαžΈ αžŸαž»αžαžŸαž”αŸ’αž”αžΆαž™αž’αžαŸ‹?"
137
  t.translate("αžαŸ’αž‰αž»αŸ†αžŸαŸ’αžšαž‘αžΆαž‰αŸ‹αž”αŸ’αžšαž‘αŸαžŸαžšαž”αžŸαŸ‹αžαŸ’αž‰αž»αŸ†αŸ”", direction="km2en")
138
 
139
  # Batch + decoding options
@@ -175,7 +194,7 @@ netra-web --port 8080 --device cpu
175
  netra-web --local-dir export # load weights from a local export dir
176
  ```
177
 
178
- A two-pane translation site (source left, output right, EN⇄KM swap button) plus a JSON API:
179
 
180
  ```bash
181
  curl -X POST http://127.0.0.1:8000/api/translate \
 
14
  ---
15
 
16
  <div align="center">
17
+ <img
18
+ src="https://raw.githubusercontent.com/netra-ai-lab/Netra-NMT/main/assets/logo.png"
19
+ width="20%"
20
+ alt="Netra Lab"
21
+ style="vertical-align: middle; margin-right: 30px;"
22
+ />
23
+ <img
24
+ src="https://raw.githubusercontent.com/netra-ai-lab/Netra-NMT/main/assets/wordmark.png"
25
+ width="20%"
26
+ alt="Netra Lab"
27
+ style="vertical-align: middle;"
28
+ />
29
  </div>
30
 
31
  <hr>
 
44
  </h2>
45
 
46
  <p align="center">
47
+ <img src="https://raw.githubusercontent.com/netra-ai-lab/Netra-NMT/main/assets/speed_benchmark.png" style="width: 1000px" align=center>
48
  </p>
49
 
50
  <p align="center">
51
+ <a href="">Inference Speed Benchmark on CPU (Intel i7-13700KF) and GPU (RTX 3060) using Greedy and Beam-5 decoding</a>
52
  </p>
53
 
54
  ## 1. Abstract
55
+ This repository presents Netra-NMT, a compact **77M-parameter** encoder-decoder transformer-based model trained from scratch on **220 million tokens** of English-Khmer parallel text (4.2M bidirectional examples). The encoder uses bidirectional self-attention, much like BERT, to capture global contextual representation. The decoder performs autoregressive generation through causal self-attention and encoder-decoder cross-attention.
56
 
57
+ Netra-NMT adopts a modern transformer recipe: **rotary position embeddings (RoPE)** in self-attention (no learned position table), **RMSNorm** with Pre-Normalization for stable optimization, **SwiGLU** feed-forward networks, and a **single embedding table shared** across the encoder input, decoder input, and tied output projection. It uses a **deep-encoder / shallow-decoder** layout (12 encoder layers, 2 decoder layers) which β€” combined with a **KV cache** for O(T) incremental decoding β€” delivers autoregressive quality at a fraction of the decoding latency (Kasai et al., 2021). Khmer text is word-segmented with **khmercut** before tokenization, so the shared 32K SentencePiece vocabulary sees real word boundaries.
58
 
59
  ## 2. Dataset
60
 
 
77
  1. **Deduplication**: exact duplicate pairs removed across all sources.
78
  2. **Length filtering**: pairs with extreme source/target length mismatches were discarded.
79
  3. **Empty/null removal**: pairs where either side was empty or below a minimum token count were dropped.
80
+ 4. **English source case-normalization**: English is NFC-normalized, whitespace-collapsed, and lowercased **only when it is the `en2km` source**, so `"I love Cambodia"` and `"i love cambodia"` map to identical model inputs. English kept as a `km2en` *target* retains its natural casing.
81
+ 5. **Khmer word segmentation**: Khmer (which is written without spaces) is segmented with **khmercut** wherever it appears β€” as the `en2km` target and the `km2en` source β€” matching the segmented tokenizer. Khmer output is de-segmented back to natural text at inference time.
82
 
83
  After cleaning, each surviving pair is duplicated in both directions (`ENβ†’KM` and `KMβ†’EN`) with a direction prefix token (`<2km>` / `<2en>`), yielding ~4.2 million training examples.
84
 
85
  ## 3. Model Architecture
86
 
87
  <div align="center">
88
+ <img src="https://raw.githubusercontent.com/netra-ai-lab/Netra-NMT/main/assets/model_architecture.png" width="70%" alt="Netra-NMT Architecture" />
89
  <p><em>Figure 1: Overview of the Netra-NMT encoder-decoder architecture. The encoder (left) processes the source sentence with bidirectional self-attention; the decoder (right) generates the target sentence autoregressively via causal self-attention and cross-attention over the encoder output. Both sides share a 32K SentencePiece tokenizer.</em></p>
90
  </div>
91
 
92
+ Netra-NMT follows an encoder-decoder transformer architecture modernized for training stability, parameter efficiency, and low-latency decoding.
93
 
94
+ **Encoder** takes the source sentence tokenized by the shared 32K SentencePiece tokenizer (Khmer is word-segmented with khmercut beforehand), and passes the sequence through **12** transformer layers with *bidirectional* self-attention (every token attends to every other token, similar to BERT). Positions are encoded with **rotary embeddings (RoPE)** applied to the queries and keys inside self-attention β€” there is no learned position table. A final RMSNorm is applied to the encoder output before it is passed to the decoder via cross-attention.
95
 
96
+ **Decoder** takes the (partially generated) target sentence through the same tokenizer and passes it through only **2** transformer layers. Each decoder layer applies three sub-layers in order: (1) *causal* (masked) self-attention with RoPE over previously generated tokens, backed by a **KV cache** for O(T) incremental decoding, (2) cross-attention over the full encoder output, and (3) a SwiGLU feed-forward block. A final RMSNorm feeds into the tied projection head. The **deep-encoder / shallow-decoder** split (12 vs 2) follows Kasai et al. (2021): most of the modeling capacity lives in the parallelizable encoder, while the thin decoder β€” the part that runs sequentially at inference β€” keeps per-step cost low without sacrificing quality.
97
 
98
  **Architectural improvements over the vanilla transformer:**
99
 
100
  | Feature | Detail |
101
  |---------|--------|
102
+ | Rotary Position Embeddings (RoPE) | Positions encoded by rotating Q/K inside self-attention β€” no learned position table, and generalizes past the training length |
103
+ | RMSNorm (Pre-Norm) | Root-mean-square normalization applied *before* each sub-layer; as stable as LayerNorm and cheaper |
104
+ | SwiGLU FFN | Feed-forward blocks use the SwiGLU activation instead of ReLU, providing richer representational capacity |
105
+ | Shared embeddings | One embedding table is shared across the encoder input, decoder input, and the tied output projection head |
106
+ | Deep encoder / shallow decoder | 12-layer encoder + 2-layer decoder (Kasai et al., 2021) β€” retains quality while sharply cutting sequential decoding cost |
107
+ | KV cache | Incremental decoding caches past keys/values, making generation O(T) instead of O(TΒ²) |
108
+ | Khmer word segmentation | Khmer is segmented with khmercut before SentencePiece so the tokenizer learns real word boundaries |
109
 
110
  **Hyperparameters:**
111
 
112
  | | |
113
  |---|---|
114
  | d_model | 512 |
115
+ | Encoder / Decoder layers | 12 / 2 |
116
  | Attention heads | 8 |
117
  | FFN hidden size | 2048 |
118
+ | Position encoding | Rotary (RoPE) |
119
+ | Normalization | RMSNorm (Pre-Norm) |
120
+ | Vocabulary | 32K (SentencePiece unigram, shared, Khmer-segmented) |
121
+ | Total parameters | ~77M |
122
 
123
  ## 4. Evaluation Results
124
 
125
  <p align="center">
126
+ <img src="https://raw.githubusercontent.com/netra-ai-lab/Netra-NMT/main/assets/metrics_benchmark.png" style="width: 1000px" align=center>
127
  </p>
128
 
129
  ## Install
 
152
  from netra_nmt import NetraTranslator
153
 
154
  t = NetraTranslator() # auto-detect GPU/CPU; downloads weights once
155
+ t.translate("Hello, how are you?", direction="en2km") # β†’ "αžŸαž½αžŸαŸ’αžαžΈαžŸαž»αžαžŸαž”αŸ’αž”αžΆαž™αž’αžαŸ‹?"
156
  t.translate("αžαŸ’αž‰αž»αŸ†αžŸαŸ’αžšαž‘αžΆαž‰αŸ‹αž”αŸ’αžšαž‘αŸαžŸαžšαž”αžŸαŸ‹αžαŸ’αž‰αž»αŸ†αŸ”", direction="km2en")
157
 
158
  # Batch + decoding options
 
194
  netra-web --local-dir export # load weights from a local export dir
195
  ```
196
 
197
+ A two-pane translation site (source left, output right, EN⇄KM swap button) and a JSON API:
198
 
199
  ```bash
200
  curl -X POST http://127.0.0.1:8000/api/translate \