Sothay commited on
Commit
d9f2d17
·
verified ·
1 Parent(s): 9988d8d

Update readme

Browse files

![image](https://cdn-uploads.huggingface.co/production/uploads/689596b75eb20f0512a0fae2/tCSxS1Glicnv3Lutr32WF.png)

Files changed (1) hide show
  1. README.md +168 -1
README.md CHANGED
@@ -1,3 +1,170 @@
1
  ---
2
- license: apache-2.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ license: gemma
3
+ language:
4
+ - en
5
+ - km
6
+ tags:
7
+ - customs
8
+ - hs-code
9
+ - classification
10
+ - cambodia
11
+ - gemma
12
+ - unsloth
13
+ - qlora
14
+ base_model:
15
+ - google/gemma-4-12B-it
16
+ pipeline_tag: text-classification
17
  ---
18
+
19
+ # Gemma‑4 HS Code Classifier (Cambodia Customs)
20
+
21
+ A **Gemma‑4‑E4B‑it** model fine‑tuned with QLoRA to classify product descriptions into **8‑digit HS codes** and return corresponding Cambodian trade rates (Customs Duty, Special Tax, VAT, Excise Tax).
22
+
23
+ Built with **[Unsloth](https://github.com/unslothai/unsloth)** for fast, memory‑efficient fine‑tuning on a single T4 GPU.
24
+
25
+ ---
26
+
27
+ ## 🎯 What it does
28
+
29
+ Given a plain‑English product description, the model generates:
30
+
31
+ ```text
32
+ HS Code: 6105.10.00
33
+ Unit: PIECE
34
+ Customs Duty: 25%
35
+ Special Tax: 0%
36
+ VAT: 10%
37
+ Excise Tax: 0%
38
+ ```
39
+
40
+ **⚠️ Important**: The rates in the text are generated by the model and **may be wrong**.
41
+ For production, always use the included **lookup table** (`hs_code_lookup.json`) – see [Production use](#-production-use) below.
42
+
43
+ ---
44
+
45
+ ## 🚀 Quick start (in Colab or locally)
46
+
47
+ ```python
48
+ from unsloth import FastModel
49
+
50
+ model, tokenizer = FastModel.from_pretrained(
51
+ "Sothay/gemma4-hscode-classifier",
52
+ load_in_4bit=True,
53
+ )
54
+
55
+ # ---------- Inference with the authoritative lookup table (recommended) ----------
56
+ import json, re
57
+
58
+ with open("hs_code_lookup.json") as f:
59
+ rate_lookup = json.load(f)
60
+
61
+ def predict_hs_code(description: str) -> dict:
62
+ messages = [
63
+ {"role": "system", "content": [{"type": "text", "text": "You are a customs compliance AI..."}]},
64
+ {"role": "user", "content": [{"type": "text", "text": f"Description: {description}"}]},
65
+ ]
66
+ inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt").to("cuda")
67
+ out = model.generate(inputs, max_new_tokens=80, do_sample=False)
68
+ text = tokenizer.decode(out[0][inputs.shape[1]:], skip_special_tokens=True)
69
+
70
+ m = re.search(r"HS Code:\s*([0-9]{4,10})", text)
71
+ code = m.group(1) if m else None
72
+ if code and code in rate_lookup:
73
+ return {"hs_code": code, "source": "lookup_table", **rate_lookup[code]}
74
+ return {"hs_code": code, "source": "model_only_UNVERIFIED", "raw_output": text}
75
+
76
+ print(predict_hs_code("Men's cotton knitted T-shirt"))
77
+ ```
78
+
79
+ ---
80
+
81
+ ## 🧠 Training details
82
+
83
+ - **Base model**: `unsloth/gemma-4-E4B-it` (4‑bit QLoRA)
84
+ - **Adapter rank**: r=16, alpha=16, targeting all language & attention layers
85
+ - **Gradient checkpointing**: Unsloth’s own implementation (avoids Gemma‑4 KV‑shared layer bug)
86
+ - **Dataset**: Custom Cambodian HS‑code dataset (`hs_code.csv`) with descriptions, codes, and official rates
87
+ - Cleaned, deduplicated, split into 90/10 train/validation
88
+ - Chat roles fixed to system/user/assistant (Gemma‑4 standard)
89
+ - **Training config**: 2 epochs, effective batch size 8, learning rate 2e‑4, linear schedule, eval & save every epoch, best model loaded
90
+ - **Hardware**: Google Colab T4 (16 GB) – peak memory ~10 GB thanks to QLoRA
91
+ - **Accuracy**: Evaluated on held‑out examples (exact HS‑code match) – see model card for current numbers
92
+
93
+ ---
94
+
95
+ ## ⚖️ Production use
96
+
97
+ > **Always use the lookup table – never trust the model’s generated rates.**
98
+
99
+ The model is a **classifier**: description → HS code.
100
+ Rates are fetched deterministically from `hs_code_lookup.json`, a file extracted from the same official tariff data used during training.
101
+
102
+ Why?
103
+ - A causal LM recalling a rate from memory will occasionally hallucinate – a customs tool with confident, wrong numbers is worse than one that says “I don’t know”.
104
+ - The lookup table guarantees 100% accuracy on rates once the HS code is correct.
105
+
106
+ The `hs_code_lookup.json` file is included in this repository and can be downloaded via:
107
+
108
+ ```python
109
+ from huggingface_hub import hf_hub_download
110
+ hf_hub_download("Sothay/gemma4-hscode-classifier", "hs_code_lookup.json")
111
+ ```
112
+
113
+ ---
114
+
115
+ ## 📦 Files in this repository
116
+
117
+ | File | Description |
118
+ |------|-------------|
119
+ | `adapter_model.safetensors` | LoRA adapter weights (few MB) |
120
+ | `tokenizer.json`, `tokenizer_config.json` | Tokenizer files |
121
+ | `hs_code_lookup.json` | Authoritative rate table for production inference |
122
+ | `README.md` | This file |
123
+
124
+ > If you need a **merged, full‑precision model** (for vLLM, TGI, etc.), generate it locally with Unsloth:
125
+ > ```python
126
+ > model.save_pretrained_merged("merged_fp16", tokenizer, save_method="merged_16bit")
127
+ > ```
128
+
129
+ ---
130
+
131
+ ## 🦙 Ollama / llama.cpp (GGUF)
132
+
133
+ Export a quantized GGUF directly from the LoRA adapter:
134
+
135
+ ```python
136
+ model.save_pretrained_gguf("gguf_model", tokenizer, quantization_method="q4_k_m")
137
+ ```
138
+
139
+ Then use with Ollama (see [`Modelfile` example](https://ollama.com) – set temperature 0, deterministic sampling).
140
+
141
+ ---
142
+
143
+ ## 📊 Example predictions
144
+
145
+ | Description | Predicted HS Code | Unit | CD | ST | VAT | ET |
146
+ |-------------|-------------------|------|----|----|-----|----|
147
+ | Toyota Hilux pickup, diesel 2.8L | 8704 | u | 35% | 50% | 10% | 0% |
148
+ | iPhone 15 Pro Max 256GB | 8517 | u | 0% | 0% | 10% | 0% |
149
+ | Heineken beer 330ml can | 2203 | l | 35% | 30% | 10% | 0% |
150
+
151
+ *(Rates from lookup table – not generated by the model.)*
152
+
153
+ ---
154
+
155
+ ## 📝 License
156
+
157
+ This model is a derivative of **Gemma‑4‑E4B‑it** and is subject to the [Gemma license](https://ai.google.dev/gemma/terms).
158
+ The HS‑code dataset and lookup table are the property of their respective owners.
159
+
160
+ ---
161
+
162
+ ## 🙏 Acknowledgments
163
+
164
+ - [Unsloth](https://github.com/unslothai/unsloth) – made QLoRA + Gemma‑4 on a T4 effortless
165
+ - [Google DeepMind](https://deepmind.google) – for the Gemma family of models
166
+
167
+ ---
168
+
169
+ **Author**: [Sothay](https://huggingface.co/Sothay)
170
+ **Model card version**: 1.0