🧠 disable thinking mode: empty <think> block + faster eval with eos_token_id
Browse files
notebooks/qwen35-2b-bash-finetune.ipynb
CHANGED
|
@@ -188,35 +188,7 @@
|
|
| 188 |
"execution_count": null,
|
| 189 |
"metadata": {},
|
| 190 |
"outputs": [],
|
| 191 |
-
"source": [
|
| 192 |
-
"FastLanguageModel.for_inference(model)\n",
|
| 193 |
-
"\n",
|
| 194 |
-
"test_cases = [\n",
|
| 195 |
-
" \"git space push space dash u space origin space main\",\n",
|
| 196 |
-
" \"find dot dash name star dot txt\",\n",
|
| 197 |
-
" \"docker space run space dash dash rm space dash p space eight zero eight zero colon eight zero space nginx\",\n",
|
| 198 |
-
" \"chmod space zero seven five five space slash usr slash local slash bin slash deploy dot sh\",\n",
|
| 199 |
-
" \"ssh space dash i space tilde slash dot ssh slash id underscore rsa space root at one nine two dot one six eight dot one dot one\",\n",
|
| 200 |
-
"]\n",
|
| 201 |
-
"\n",
|
| 202 |
-
"for dictated in test_cases:\n",
|
| 203 |
-
" messages = [\n",
|
| 204 |
-
" {\"role\": \"system\", \"content\": \"Reconstruct the intended syntax from the dictated text. Output only the result.\"},\n",
|
| 205 |
-
" {\"role\": \"user\", \"content\": dictated},\n",
|
| 206 |
-
" ]\n",
|
| 207 |
-
" inputs = tokenizer.apply_chat_template(\n",
|
| 208 |
-
" messages, tokenize=True, add_generation_prompt=True, return_tensors=\"pt\"\n",
|
| 209 |
-
" ).to(model.device)\n",
|
| 210 |
-
"\n",
|
| 211 |
-
" outputs = model.generate(\n",
|
| 212 |
-
" input_ids=inputs, max_new_tokens=128, temperature=0.0,\n",
|
| 213 |
-
" do_sample=False, use_cache=True,\n",
|
| 214 |
-
" )\n",
|
| 215 |
-
" response = tokenizer.decode(outputs[0][inputs.shape[-1]:], skip_special_tokens=True)\n",
|
| 216 |
-
" print(f\"IN: {dictated}\")\n",
|
| 217 |
-
" print(f\"OUT: {response}\")\n",
|
| 218 |
-
" print()"
|
| 219 |
-
]
|
| 220 |
},
|
| 221 |
{
|
| 222 |
"cell_type": "markdown",
|
|
@@ -230,77 +202,7 @@
|
|
| 230 |
"execution_count": null,
|
| 231 |
"metadata": {},
|
| 232 |
"outputs": [],
|
| 233 |
-
"source": [
|
| 234 |
-
"from difflib import SequenceMatcher\n",
|
| 235 |
-
"import time\n",
|
| 236 |
-
"\n",
|
| 237 |
-
"test_dataset = load_dataset(\n",
|
| 238 |
-
" \"json\",\n",
|
| 239 |
-
" data_files=\"./data/training/data/bash-v2/minimal/test.jsonl\",\n",
|
| 240 |
-
" split=\"train\",\n",
|
| 241 |
-
")\n",
|
| 242 |
-
"\n",
|
| 243 |
-
"results = {\"exact\": 0, \"near\": 0, \"partial\": 0, \"wrong\": 0}\n",
|
| 244 |
-
"total_time = 0\n",
|
| 245 |
-
"errors = []\n",
|
| 246 |
-
"\n",
|
| 247 |
-
"for i, example in enumerate(test_dataset):\n",
|
| 248 |
-
" msgs = example[\"messages\"]\n",
|
| 249 |
-
" dictated = msgs[1][\"content\"]\n",
|
| 250 |
-
" expected = msgs[2][\"content\"]\n",
|
| 251 |
-
"\n",
|
| 252 |
-
" messages = [\n",
|
| 253 |
-
" {\"role\": \"system\", \"content\": msgs[0][\"content\"]},\n",
|
| 254 |
-
" {\"role\": \"user\", \"content\": dictated},\n",
|
| 255 |
-
" ]\n",
|
| 256 |
-
" inputs = tokenizer.apply_chat_template(\n",
|
| 257 |
-
" messages, tokenize=True, add_generation_prompt=True, return_tensors=\"pt\"\n",
|
| 258 |
-
" ).to(model.device)\n",
|
| 259 |
-
"\n",
|
| 260 |
-
" t0 = time.time()\n",
|
| 261 |
-
" outputs = model.generate(\n",
|
| 262 |
-
" input_ids=inputs, max_new_tokens=256, temperature=0.0,\n",
|
| 263 |
-
" do_sample=False, use_cache=True,\n",
|
| 264 |
-
" )\n",
|
| 265 |
-
" t1 = time.time()\n",
|
| 266 |
-
" total_time += (t1 - t0)\n",
|
| 267 |
-
"\n",
|
| 268 |
-
" response = tokenizer.decode(outputs[0][inputs.shape[-1]:], skip_special_tokens=True).strip()\n",
|
| 269 |
-
" similarity = SequenceMatcher(None, response, expected).ratio()\n",
|
| 270 |
-
"\n",
|
| 271 |
-
" if response == expected:\n",
|
| 272 |
-
" results[\"exact\"] += 1\n",
|
| 273 |
-
" elif similarity >= 0.9:\n",
|
| 274 |
-
" results[\"near\"] += 1\n",
|
| 275 |
-
" elif similarity >= 0.7:\n",
|
| 276 |
-
" results[\"partial\"] += 1\n",
|
| 277 |
-
" else:\n",
|
| 278 |
-
" results[\"wrong\"] += 1\n",
|
| 279 |
-
" errors.append((dictated[:60], expected[:60], response[:60]))\n",
|
| 280 |
-
"\n",
|
| 281 |
-
" if (i + 1) % 50 == 0:\n",
|
| 282 |
-
" print(f\" {i+1}/{len(test_dataset)}...\")\n",
|
| 283 |
-
"\n",
|
| 284 |
-
"n = len(test_dataset)\n",
|
| 285 |
-
"print(f\"\\n{'='*50}\")\n",
|
| 286 |
-
"print(f\"QWEN3.5-2B EVALUATION ({n} cases)\")\n",
|
| 287 |
-
"print(f\"{'='*50}\")\n",
|
| 288 |
-
"print(f\"Exact match: {results['exact']:4d} / {n} ({results['exact']/n*100:.1f}%)\")\n",
|
| 289 |
-
"print(f\"Near (>90%): {results['near']:4d} / {n} ({results['near']/n*100:.1f}%)\")\n",
|
| 290 |
-
"print(f\"Partial (70-90): {results['partial']:3d} / {n} ({results['partial']/n*100:.1f}%)\")\n",
|
| 291 |
-
"print(f\"Wrong (<70%): {results['wrong']:3d} / {n} ({results['wrong']/n*100:.1f}%)\")\n",
|
| 292 |
-
"print(f\"\\nEffective accuracy: {(results['exact']+results['near'])/n*100:.1f}%\")\n",
|
| 293 |
-
"print(f\"Avg inference time: {total_time/n:.2f}s\")\n",
|
| 294 |
-
"print(f\"Peak memory: {torch.cuda.max_memory_allocated() / 1e9:.2f} GB\")\n",
|
| 295 |
-
"\n",
|
| 296 |
-
"if errors:\n",
|
| 297 |
-
" print(f\"\\nSample errors ({len(errors)} total):\")\n",
|
| 298 |
-
" for d, e, r in errors[:5]:\n",
|
| 299 |
-
" print(f\" IN: {d}\")\n",
|
| 300 |
-
" print(f\" EXP: {e}\")\n",
|
| 301 |
-
" print(f\" GOT: {r}\")\n",
|
| 302 |
-
" print()"
|
| 303 |
-
]
|
| 304 |
},
|
| 305 |
{
|
| 306 |
"cell_type": "markdown",
|
|
|
|
| 188 |
"execution_count": null,
|
| 189 |
"metadata": {},
|
| 190 |
"outputs": [],
|
| 191 |
+
"source": "FastLanguageModel.for_inference(model)\n\ntext_tokenizer = tokenizer.tokenizer if hasattr(tokenizer, 'tokenizer') else tokenizer\neos_id = text_tokenizer.convert_tokens_to_ids(\"<|im_end|>\")\n\ntest_cases = [\n \"git space push space dash u space origin space main\",\n \"find dot dash name star dot txt\",\n \"docker space run space dash dash rm space dash p space eight zero eight zero colon eight zero space nginx\",\n \"chmod space zero seven five five space slash usr slash local slash bin slash deploy dot sh\",\n \"ssh space dash i space tilde slash dot ssh slash id underscore rsa space root at one nine two dot one six eight dot one dot one\",\n]\n\nfor dictated in test_cases:\n prompt = \"<|im_start|>system\\nReconstruct the intended syntax from the dictated text. Output only the result.<|im_end|>\\n\"\n prompt += f\"<|im_start|>user\\n{dictated}<|im_end|>\\n\"\n prompt += \"<|im_start|>assistant\\n<think>\\n</think>\\n\"\n\n inputs = text_tokenizer(prompt, return_tensors=\"pt\").to(model.device)\n\n outputs = model.generate(\n **inputs, max_new_tokens=64, temperature=0.0,\n do_sample=False, use_cache=True, eos_token_id=eos_id,\n )\n response = text_tokenizer.decode(outputs[0][inputs[\"input_ids\"].shape[-1]:], skip_special_tokens=True)\n print(f\"IN: {dictated}\")\n print(f\"OUT: {response}\")\n print()"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
},
|
| 193 |
{
|
| 194 |
"cell_type": "markdown",
|
|
|
|
| 202 |
"execution_count": null,
|
| 203 |
"metadata": {},
|
| 204 |
"outputs": [],
|
| 205 |
+
"source": "from difflib import SequenceMatcher\nimport time\n\ntext_tokenizer = tokenizer.tokenizer if hasattr(tokenizer, 'tokenizer') else tokenizer\neos_id = text_tokenizer.convert_tokens_to_ids(\"<|im_end|>\")\n\ntest_dataset = load_dataset(\n \"json\",\n data_files=\"./data/training/data/bash-v2/minimal/test.jsonl\",\n split=\"train\",\n)\n\nresults = {\"exact\": 0, \"near\": 0, \"partial\": 0, \"wrong\": 0}\ntotal_time = 0\nerrors = []\n\nfor i, example in enumerate(test_dataset):\n msgs = example[\"messages\"]\n dictated = msgs[1][\"content\"]\n expected = msgs[2][\"content\"]\n\n prompt = f\"<|im_start|>{msgs[0]['role']}\\n{msgs[0]['content']}<|im_end|>\\n\"\n prompt += f\"<|im_start|>user\\n{dictated}<|im_end|>\\n\"\n prompt += \"<|im_start|>assistant\\n<think>\\n</think>\\n\"\n\n inputs = text_tokenizer(prompt, return_tensors=\"pt\").to(model.device)\n\n t0 = time.time()\n outputs = model.generate(\n **inputs, max_new_tokens=64, temperature=0.0,\n do_sample=False, use_cache=True, eos_token_id=eos_id,\n )\n t1 = time.time()\n total_time += (t1 - t0)\n\n response = text_tokenizer.decode(outputs[0][inputs[\"input_ids\"].shape[-1]:], skip_special_tokens=True).strip()\n similarity = SequenceMatcher(None, response, expected).ratio()\n\n if response == expected:\n results[\"exact\"] += 1\n elif similarity >= 0.9:\n results[\"near\"] += 1\n elif similarity >= 0.7:\n results[\"partial\"] += 1\n else:\n results[\"wrong\"] += 1\n errors.append((dictated[:60], expected[:60], response[:60]))\n\n if (i + 1) % 10 == 0:\n elapsed = total_time / (i + 1)\n print(f\" {i+1}/{len(test_dataset)} | avg {elapsed:.1f}s/ex | exact so far: {results['exact']}/{i+1}\")\n\nn = len(test_dataset)\nprint(f\"\\n{'='*50}\")\nprint(f\"QWEN3.5-2B EVALUATION ({n} cases)\")\nprint(f\"{'='*50}\")\nprint(f\"Exact match: {results['exact']:4d} / {n} ({results['exact']/n*100:.1f}%)\")\nprint(f\"Near (>90%): {results['near']:4d} / {n} ({results['near']/n*100:.1f}%)\")\nprint(f\"Partial (70-90): {results['partial']:3d} / {n} ({results['partial']/n*100:.1f}%)\")\nprint(f\"Wrong (<70%): {results['wrong']:3d} / {n} ({results['wrong']/n*100:.1f}%)\")\nprint(f\"\\nEffective accuracy: {(results['exact']+results['near'])/n*100:.1f}%\")\nprint(f\"Avg inference time: {total_time/n:.2f}s\")\nprint(f\"Peak memory: {torch.cuda.max_memory_allocated() / 1e9:.2f} GB\")\n\nif errors:\n print(f\"\\nSample errors ({len(errors)} total):\")\n for d, e, r in errors[:5]:\n print(f\" IN: {d}\")\n print(f\" EXP: {e}\")\n print(f\" GOT: {r}\")\n print()"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 206 |
},
|
| 207 |
{
|
| 208 |
"cell_type": "markdown",
|