Fine-tuning adapts a pre-trained model to your specific domain, vocabulary, and task requirements. For Chinese applications — legal documents, medical records, financial reports, customer service — fine-tuning can improve accuracy by 20-40% over prompt engineering alone. This guide covers the complete fine-tuning workflow for Chinese AI models.
When to Fine-Tune vs. Prompt Engineer
| Scenario | Prompt Engineering | Fine-Tuning |
|---|---|---|
| General Q&A | Sufficient | Overkill |
| Domain-specific terminology | Limited | Recommended |
| Consistent output format | Works | More reliable |
| Private/sensitive data | Sends data to API | Train once, deploy locally |
| Real-time low latency | Network dependent | Faster inference |
| Budget < $500 | Cost-effective | Expensive |
Chinese Model Fine-Tuning Landscape
| Model | Fine-Tuning Access | Cost Level | Best For |
|---|---|---|---|
| deepseek DeepSeek-V4 | API + Local | Medium | Reasoning tasks, coding |
| zhipu GLM-5.1 | API (Zhipu AI) | Medium | Chinese text, creative writing |
| qwen Qwen-Plus | API + Local (LoRA) | Low | General purpose, fast training |
| kimi Kimi-K3 | API (Moonshot) | High | Long-document understanding |
Data Preparation for Chinese Fine-Tuning
Data quality is the single most important factor in fine-tuning success. For Chinese models:
1. Conversation Format
[
{
"messages": [
{"role": "system", "content": "你是一位专业的中医养生顾问。"},
{"role": "user", "content": "我最近失眠,有什么调理建议?"},
{"role": "assistant", "content": "失眠在中医多与心脾两虚或肝郁化火有关。建议您..."}
]
},
{
"messages": [
{"role": "system", "content": "你是一位专业的中医养生顾问。"},
{"role": "user", "content": "夏天容易上火怎么办?"},
{"role": "assistant", "content": "夏季心火易旺,建议..."}
]
}
]
2. Data Quality Checklist
- Language consistency: All examples in the same language (don't mix Chinese and English arbitrarily)
- Format consistency: Every example follows the exact same structure
- Answer completeness: Assistant responses should be fully self-contained
- No hallucinations: Verify facts in training data; the model will learn wrong answers too
- Diversity: Cover edge cases, different phrasings, and various difficulty levels
- Minimum size: 500 examples for noticeable improvement; 2000+ for production quality
3. Data Augmentation for Chinese
import jieba
import random
# Technique 1: Synonym replacement
def augment_synonyms(text, n=2):
words = list(jieba.cut(text))
# Replace n random words with synonyms
# (Use a Chinese thesaurus or synonym dictionary)
return text
# Technique 2: Back-translation
def back_translate(text):
# Chinese -> English -> Chinese
# Uses translation API to create paraphrased versions
pass
# Technique 3: Sentence restructuring
def restructure(text):
# Change word order while preserving meaning
# 因为...所以... -> 之所以...是因为...
pass
Training Strategy: LoRA for Efficiency
Full fine-tuning requires massive GPU resources. LoRA (Low-Rank Adaptation) trains small adapter layers instead:
# Install dependencies
# pip install peft transformers datasets
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM, AutoTokenizer
# Load base model
model_name = "Qwen/Qwen-7B-Chat"
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
# Configure LoRA
lora_config = LoraConfig(
r=16, # Rank (8-64 typical)
lora_alpha=32, # Scaling factor
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
# Wrap model with LoRA
model = get_peft_model(model, lora_config)
print(f"Trainable parameters: {model.print_trainable_parameters()}")
# Output: trainable params: 20M || all params: 7.7B || trainable%: 0.26%
Training Loop
from transformers import TrainingArguments, Trainer
from datasets import load_dataset
# Load your Chinese dataset
dataset = load_dataset("json", data_files="chinese_training_data.jsonl")
def format_prompt(example):
messages = example["messages"]
text = tokenizer.apply_chat_template(messages, tokenize=False)
return {"text": text}
dataset = dataset.map(format_prompt)
training_args = TrainingArguments(
output_dir="./chinese_lora_model",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
warmup_steps=100,
logging_steps=10,
save_steps=500,
fp16=True,
optim="adamw_torch"
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=dataset["train"],
data_collator=lambda x: tokenizer([d["text"] for d in x], padding=True, return_tensors="pt")
)
trainer.train()
# Save adapter
model.save_pretrained("./chinese_lora_adapter")
tokenizer.save_pretrained("./chinese_lora_adapter")
Hyperparameter Guidelines
| Parameter | Small Dataset (<1K) | Medium (1K-10K) | Large (>10K) |
|---|---|---|---|
| Learning Rate | 1e-4 | 2e-4 | 1e-4 |
| LoRA Rank (r) | 8 | 16 | 32 |
| Epochs | 5-10 | 3-5 | 1-3 |
| Batch Size | 2-4 | 4-8 | 8-16 |
| Warmup Steps | 50 | 100 | 500 |
Evaluation
Don't just train — measure. Split your data 80/10/10 (train/validation/test):
def evaluate_model(model, tokenizer, test_dataset):
scores = []
for example in test_dataset:
# Generate response
input_text = tokenizer.apply_chat_template(
example["messages"][:-1], # Exclude answer
tokenize=False
)
inputs = tokenizer(input_text, return_tensors="pt")
outputs = model.generate(
**inputs,
max_new_tokens=200,
temperature=0.3,
do_sample=True
)
generated = tokenizer.decode(outputs[0], skip_special_tokens=True)
expected = example["messages"][-1]["content"]
# Calculate similarity (use BLEU, ROUGE, or embedding similarity)
score = calculate_similarity(generated, expected)
scores.append(score)
return sum(scores) / len(scores)
# Target: > 0.85 similarity for production deployment
Deployment Options
Option 1: Merge and Self-Host
# Merge LoRA weights into base model
from peft import AutoPeftModelForCausalLM
merged_model = model.merge_and_unload()
merged_model.save_pretrained("./merged_chinese_model")
# Deploy with vLLM for fast inference
# vllm serve ./merged_chinese_model --tensor-parallel-size 1
Option 2: Use Provider Fine-Tuning APIs
For teams without GPU infrastructure, use cloud fine-tuning:
- Zhipu AI: Upload JSONL → Train → Deploy with API key
- DeepSeek Platform: Similar workflow, supports SFT and RLHF
- Alibaba Cloud (Qwen): PAI platform with AutoML for hyperparameter tuning
Option 3: Use TokenEase with Base Models
If fine-tuning isn't feasible, use advanced prompting with base models through TokenEase:
# Instead of fine-tuning, use system prompt + RAG
messages = [
{"role": "system", "content": "你是一位资深中医养生专家,拥有30年临床经验。请基于以下参考资料回答问题。"},
{"role": "user", "content": f"参考资料:\n{retrieved_docs}\n\n问题:{user_question}"}
]
response = requests.post(
"https://tokenease.io/v1/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"model": "zhipu", "messages": messages}
)
Common Pitfalls
- Overfitting: Model memorizes training data instead of learning patterns. Use more data, lower epochs, or higher dropout.
- Catastrophic forgetting: Model loses general capabilities. Use lower learning rates and mix general data with domain data.
- Data leakage: Test examples appear in training data. Always shuffle and verify splits.
- Encoding issues: Chinese text must be UTF-8. Verify your JSONL files don't have encoding errors.
- Format drift: Training format must match inference format exactly. Use the same chat template.
Conclusion
Fine-tuning Chinese AI models is accessible with modern tools like LoRA and PEFT. Start with 500+ high-quality examples, use LoRA for efficiency, evaluate rigorously, and deploy with vLLM for fast inference.
For most teams, the RAG + prompting approach through TokenEase delivers sufficient accuracy without the complexity of fine-tuning. Reserve fine-tuning for cases where you need consistent, low-latency, domain-specific outputs at scale.
Start with Base Models
Get $1 free API credit to test if prompting + RAG meets your needs before investing in fine-tuning.
Test Base Models