Why SFT exists
- Scripted full-solve trajectories teach
<tool_call> format and evidence gathering.
- RL (GRPO-style) then improves when to explore vs close and how to cite.
SFT alone often explores well but fails on clean close_case / citations. Prefer the RL weights for demos and eval.
Load
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import PeftModel
BASE = "Qwen/Qwen2.5-3B-Instruct"
ADAPTER = "VaidikML0508/qwen2.5-3b-investigation-sft"
bnb = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float16,
bnb_4bit_use_double_quant=True,
)
tok = AutoTokenizer.from_pretrained(BASE, trust_remote_code=True)
if tok.pad_token is None:
tok.pad_token = tok.eos_token
model = AutoModelForCausalLM.from_pretrained(
BASE, quantization_config=bnb, device_map="auto", trust_remote_code=True
)
model = PeftModel.from_pretrained(model, ADAPTER)
model.eval()
Exactly one tool call per turn:
<tool_call>{"name":"call_action","arguments":{"action_name":"ACTION","arguments_json":"{}"}}</tool_call>
<tool_call>{"name":"close_case","arguments":{"culprit":"NAME","citations_json":"[\"ev1\",\"ev2\"]"}}</tool_call>
Needs a case environment (unlocked actions + observations). See the RL model card for a fuller multi-turn inference loop.
Quick generate
messages = [
{"role": "system", "content": "You are an investigation agent. Output exactly ONE <tool_call>...</tool_call> per turn."},
{"role": "user", "content": "Case brief: ...\nUnlocked: interview_witness\nDiscovered: []\nCall one tool."},
]
prompt = tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tok(prompt, return_tensors="pt").to(model.device)
out = model.generate(**inputs, max_new_tokens=160, temperature=0.3, do_sample=True,
pad_token_id=tok.pad_token_id)
print(tok.decode(out[0][inputs["input_ids"].shape[-1]:], skip_special_tokens=True))
Collection
Part of Mystery Investigation Agent: dataset → SFT (this) → RL.