Keural is a bilingual Korean–English Mixture-of-Experts language model trained entirely from scratch.
This is the DPO (Direct Preference Optimization) checkpoint at step 3,500 (~50% of 1 epoch), aligned from the Keural SFT-18k base using human preference data.
DPO alignment improves response quality, instruction-following, and reduces off-topic outputs compared to the SFT base.
Model Details
Property
Value
Architecture
Mixtral-style MoE (8 experts, top-2 routing)
Parameters
14.83B total / ~7.42B active per token
Layers
24
Hidden size
4096
Attention heads
32 (GQA — 8 KV heads)
Expert intermediate size
5632
Context length
4096 tokens
Vocabulary
131,074 (131,072 SPM + `<
RoPE theta
500,000
Sliding window
512 (alternating every other layer)
Dtype
bfloat16
Languages
Korean (primary), English
Full Training Pipeline
Stage
Steps
Tokens
Data
Pretraining Stage 1
100,000
~50B
Korean + English web corpus
Pretraining Stage 2
120,000
~13B
Korean + English web corpus (continued)
SFT
18,000
710M
mkd-chanwoo/keural-SFT (1.14M ChatML samples)
DPO (this checkpoint)
3,500 / 6,927
—
keural-dpo-raw (440K preference pairs)
DPO Hyperparameters
Hyperparameter
Value
Learning rate
2e-6 → 2e-7 cosine decay
Warmup steps
100
Beta (KL coefficient)
0.1
Effective batch size
64 (2 per GPU × 16 grad accum × 2 GPUs)
Max sequence length
1024 tokens
Optimizer
AdamW (β1=0.9, β2=0.95, ε=1e-8)
Weight decay
0.1
Max steps
6,927 (1 epoch over 440K pairs)
Hardware
2× NVIDIA H200 SXM (139 GiB each)
Parallelism
FSDP FULL_SHARD (ZeRO-3 equivalent)
Precision
bfloat16 + gradient checkpointing
SFT Hyperparameters (base checkpoint)
Hyperparameter
Value
Learning rate
1e-5 → 1e-6 cosine decay
Effective batch size
64 (4 per GPU × 8 grad accum × 2 GPUs)
Max sequence length
4096 tokens
Weight decay
0.05
Steps
18,000
Chat Format (ChatML)
This model uses ChatML format. You must use this exact format.
<|im_start|>system
You are a helpful bilingual Korean-English assistant.<|im_end|>
<|im_start|>user
안녕하세요! 오늘 날씨가 어때요?<|im_end|>
<|im_start|>assistant
The model generates until it produces <|im_end|> (token ID 131073).
Tip: Always include a system prompt. The model responds in the same language as the user when instructed to do so.
How to Use
With transformers
python
1from transformers import AutoTokenizer, AutoModelForCausalLM
2import torch
34model_id ="mkd-hossain/keural-dpo-3500"56tokenizer = AutoTokenizer.from_pretrained(model_id)7model = AutoModelForCausalLM.from_pretrained(8 model_id,9 torch_dtype=torch.bfloat16,10 device_map="auto",11)1213messages =[14{"role":"system","content":"You are a helpful bilingual Korean-English assistant. Always respond in the same language as the user."},15{"role":"user","content":"파이썬에서 리스트를 정렬하는 방법을 알려주세요."},16]1718text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)19inputs = tokenizer(text, return_tensors="pt").to(model.device)2021with torch.no_grad():22 output = model.generate(23**inputs,24 max_new_tokens=512,25 temperature=0.7,26 top_p=0.9,27 repetition_penalty=1.1,28 no_repeat_ngram_size=8,29 do_sample=True,30 eos_token_id=131073,# <|im_end|>31)3233response = tokenizer.decode(output[0][inputs.input_ids.shape[1]:], skip_special_tokens=False)34response = response.split("<|im_end|>")[0].strip()35print(response)
1from openai import OpenAI
23client = OpenAI(base_url="http://localhost:8000/v1", api_key="none")45response = client.chat.completions.create(6 model="mkd-hossain/keural-dpo-3500",7 messages=[8{"role":"system","content":"You are a helpful bilingual assistant. Respond in the same language as the user."},9{"role":"user","content":"한국의 수도는 어디인가요?"},10],11 max_tokens=512,12 temperature=0.7,13)14print(response.choices[0].message.content)
1prompt =(2"<|im_start|>system\n"3"You are a helpful bilingual Korean-English assistant. "4"Always respond in the same language as the user.\n"5"<|im_end|>\n"6"<|im_start|>user\n"7"Tell me about Seoul.<|im_end|>\n"8"<|im_start|>assistant\n"9)
Special Tokens
Token
ID
Purpose
`<
im_start
>`
`<
im_end
>`
<bos>
1
Beginning of sequence
<eos>
2
End of sequence
<pad>
0
Padding
Important: Always set eos_token_id=131073 (<|im_end|>) when generating. Do not use eos_token_id=2.