ririye/restaurant-finder-qwen25-7b-lora
qwen25-7b-restaurant-react-lora-a100
A LoRA adapter for Qwen/Qwen2.5-7B-Instruct that teaches the base model to drive the anything-finder restaurant-search agent: a four-tool ReAct loop over OpenStreetMap data (Nominatim geocoding + Overpass POI search).
The adapter is distilled from Claude Sonnet trajectories — the teacher ran the real agent against a local Dallas OSM extract, and every tool call, tool result, and final recommendation was captured verbatim.
Tools the adapter is trained to call
Tool JSON schemas ship with this repo as tool_schemas.json, generated from the live @tool objects so they cannot drift from the app.
Training data
- Training examples: 333
- Validation examples: 37
Records are OpenAI-style tool-calling chat transcripts built from the agent's full message log — not flattened prompt/completion pairs. See src/training/dataset.py in the source repo for the validation rules (a row is dropped when a tool_call_id is unresolved or unanswered, when the final turn is not a tool-call-free assistant message, or when that turn is empty).
Training procedure
- Base model:
Qwen/Qwen2.5-7B-Instruct(bfloat16) - LoRA rank / alpha / dropout:
16/32/0.05 - Target modules:
q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj - Excluded modules: (none)
- Sequence length:
4096(overlong rows:drop) - Epochs:
3, LR0.0001(cosine), optimizeradamw_torch_fused - Effective batch:
4x2grad-accum - Seed:
20260902 - Final training loss:
0.4184 - Final validation loss:
0.5309
Two caveats worth knowing
- Assistant-only loss via incremental rendering. Qwen chat templates lack
{% generation %}, so TRL'sassistant_only_losscannot be used. Labels are masked by renderingmessages[:i]andmessages[:i+1]and unmasking the delta. System, user, and tool spans contribute no loss; every assistant turn does. - Trained non-thinking. The dataset renders with
enable_thinking: false— the captured trajectories carry no reasoning content, so prompt it the same way at inference.
Serving with vLLM
vllm serve Qwen/Qwen2.5-7B-Instruct \
--enable-lora --lora-modules af-lora=/adapters/af-lora \
--max-lora-rank 16 --api-key EMPTYThen point the app at it:
LLM_BACKEND=lora LLM_MODEL_LORA=af-lora LLM_BASE_URL=http://localhost:8000/v1Evaluation
The source repo renders a three-way comparison (Claude Sonnet vs. the raw base model vs. this adapter) over an identical slice of queries — final answers plus telemetry (tool paths, per-call tokens, latency, cost) — with make compare.
