Views
No views yet
npc_model_q4.gguf, 4.58 GB)llama.cpp / llama-cpp-python, CPU or GPU (n_gpu_layers configurable)detect_lang() finds a mismatch
between the response language and the user's spoken language)world_context (civilization, location, role/name, resolved historical year)1from llama_cpp import Llama
2from huggingface_hub import hf_hub_download
3
4model_path = hf_hub_download(
5 repo_id="omaraboelmaaty/pastport-npc-llama3-gguf",
6 filename="npc_model_q4.gguf",
7)
8
9llm = Llama(
10 model_path=model_path,
11 n_ctx=2048,
12 n_threads=8,
13 n_gpu_layers=35, # set to 0 for CPU-only inference
14 verbose=False,
15)
16
17system_prompt = """You are a historical NPC.
18
19Year: -41
20Location: Alexandria
21Civilization: Ptolemaic Egypt
22Identity: Cleopatra VII
23
24Return ONLY JSON:
25
26{
27 "response": "...",
28 "anim_cues": {
29 "emotion": ["neutral"],
30 "facial_expression": ["neutral"],
31 "gesture": ["idle"],
32 "head_movement": ["still"],
33 "tts_style": ["calm"]
34 }
35}
36
37Rules:
38- Stay in character
39- No modern knowledge
40- Short replies
41
42You MUST respond in English only.
43"""
44
45output = llm.create_chat_completion(
46 messages=[
47 {"role": "system", "content": system_prompt},
48 {"role": "user", "content": "What do you think of Rome?"},
49 ],
50 temperature=0.25,
51 max_tokens=400,
52 repeat_penalty=1.3,
53 response_format={"type": "json_object"}, # llama.cpp JSON-mode, enforces valid JSON output
54)
55print(output["choices"][0]["message"]["content"])
56# -> {"response": "...", "anim_cues": {"emotion": ["wary"], ...}}Note: the served system prompt is plain text passed throughllama-cpp-python'screate_chat_completion(which applies whatever chat template is embedded in the GGUF's metadata), not the raw<|system|>/<|user|>/<|assistant|>string format used during Stage 2 fine-tuning. If you notice degraded instruction-following or JSON adherence compared to the training-time examples, this template mismatch is the most likely first place to look.
meta-llama/Meta-Llama-3-8B-Instruct using QLoRA (4-bit NF4 double-quantized
base + LoRA adapters, via HuggingFace transformers + peft + bitsandbytes), in two stages:stage1_train.jsonl / stage1_val.jsonl).
LoRA rank 8, alpha 16, target modules q_proj/v_proj, dropout 0.05. 2 epochs, learning rate
2e-4, batch size 1 with gradient accumulation 8, fp16.QA_with_anim_cues_v2.jsonl) that adds a JSON anim_cues field alongside the text response.
2 epochs, learning rate 1e-4, same batch/accumulation settings. Uses a custom
<|system|>/<|user|>/<|assistant|> prompt template with the loss masked to only the assistant
turn.merge_lora_to_base.py, CPU merge,
saved as safetensors), then converted to GGUF and quantized to Q4 (npc_model_q4.gguf,
4.58 GB) via llama.cpp for local CPU/GPU inference.1{
2 "response": "Wars that devastated Europe. Millions died, empires fell.",
3 "anim_cues": {
4 "emotion": ["somber"],
5 "facial_expression": ["serious"],
6 "gesture": ["hand_on_chest"],
7 "head_movement": ["shake_head"],
8 "tts_style": ["reflective"]
9 }
10}anim_cues drives the Unity-side NPC animation and TTS-style selection alongside the spoken
response text — this model was trained to be a full expressive-dialogue controller, not just a
text generator.