New web interface, move llm engine to separate process

This commit is contained in:
2025-05-20 09:43:17 +02:00
parent 895a533e01
commit d4a4902b94
137 changed files with 4850 additions and 3503 deletions

33
tools/qwq_train/setup.py Normal file
View File

@@ -0,0 +1,33 @@
from setuptools import setup, find_packages
setup(
name="train",
version="0.1.0",
packages=find_packages(),
scripts=[
'bin/train'
],
install_requires=[
'accelerate>=0.26.0',
'bitsandbytes>=0.45.0',
'black>=22.0.0',
'datasets>=2.14.6',
'einops>=0.7.0',
'flake8>=4.0.0',
'ipykernel>=6.0.0',
'ipywidgets>=8.0.0',
'peft>=0.8.0',
'pytest-cov>=4.0.0',
'pytest>=7.0.0',
'pyyaml>=6.0',
'requests>=2.28.0',
'sentencepiece>=0.1.99',
'torch>=2.0.0',
'transformers>=4.30.0',
'trl>=0.7.8',
'unsloth>=2025.3',
'vllm==0.8.2',
],
python_requires='>=3.10',
)

View File

View File

@@ -0,0 +1,316 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "d4c7c96e",
"metadata": {},
"outputs": [],
"source": [
"%pip install transformers>=4.51.0"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3edd43ac",
"metadata": {},
"outputs": [],
"source": [
"# None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.\n",
"%pip install torch"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d41f8851",
"metadata": {},
"outputs": [],
"source": [
"%pip install unsloth"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1b5a6da6",
"metadata": {},
"outputs": [],
"source": [
"%pip install datasets"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d5256285",
"metadata": {},
"outputs": [],
"source": [
"from unsloth import FastLanguageModel, is_bfloat16_supported"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "88abe86a",
"metadata": {},
"outputs": [],
"source": [
"from transformers import AutoTokenizer, TrainingArguments\n",
"from trl import SFTTrainer, DataCollatorForCompletionOnlyLM"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b404a9db",
"metadata": {},
"outputs": [],
"source": [
"import dataset"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "01519eee",
"metadata": {},
"outputs": [],
"source": [
"model_name = \"unsloth/Qwen3-0.6B-unsloth-bnb-4bit\"\n",
"#model_name = \"Qwen/Qwen3-0.6B\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "04e1aad4",
"metadata": {},
"outputs": [],
"source": [
"\n",
"# load the tokenizer and the model\n",
"tokenizer = AutoTokenizer.from_pretrained(model_name)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "31f2451c",
"metadata": {},
"outputs": [],
"source": [
"model, _returned_tokenizer = FastLanguageModel.from_pretrained(\n",
" model_name,\n",
" gpu_memory_utilization = 0.5, # Reduce if out of memory\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2dddcb05",
"metadata": {},
"outputs": [],
"source": [
"# prepare the model input\n",
"prompt = \"Give me a short introduction to large language model.\"\n",
"messages = [\n",
" {\"role\": \"user\", \"content\": prompt}\n",
"]\n",
"text = tokenizer.apply_chat_template(\n",
" messages,\n",
" tokenize=False,\n",
" add_generation_prompt=True,\n",
" enable_thinking=True # Switches between thinking and non-thinking modes. Default is True.\n",
")\n",
"model_inputs = tokenizer([text], return_tensors=\"pt\").to(model.device)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "84a7b4cc",
"metadata": {},
"outputs": [],
"source": [
"## conduct text completion\n",
"#generated_ids = model.generate(\n",
"# **model_inputs,\n",
"# max_new_tokens=32768\n",
"#)\n",
"#output_ids = generated_ids[0][len(model_inputs.input_ids[0]):].tolist() "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "05be1a53",
"metadata": {},
"outputs": [],
"source": [
"## parsing thinking content\n",
"#try:\n",
"# # rindex finding 151668 (</think>)\n",
"# index = len(output_ids) - output_ids[::-1].index(151668)\n",
"#except ValueError:\n",
"# index = 0"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "64775c31",
"metadata": {},
"outputs": [],
"source": [
"#thinking_content = tokenizer.decode(output_ids[:index], skip_special_tokens=True).strip(\"\\n\")\n",
"#content = tokenizer.decode(output_ids[index:], skip_special_tokens=True).strip(\"\\n\")\n",
"#\n",
"#print(\"thinking content:\", thinking_content)\n",
"#print(\"content:\", content)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "48477dfd",
"metadata": {},
"outputs": [],
"source": [
"dataset = dataset.Dataset(\"/root/sia/training/config.yaml\")\n",
"dataset.validate()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "90b56737",
"metadata": {},
"outputs": [],
"source": [
"model = FastLanguageModel.get_peft_model(\n",
" model,\n",
" target_modules = [\n",
" \"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\",\n",
" \"gate_proj\", \"up_proj\", \"down_proj\",\n",
" ],\n",
" lora_dropout = 0, # Supports any, but = 0 is optimized\n",
" bias = \"none\", # Supports any, but = \"none\" is optimized\n",
" use_gradient_checkpointing = \"unsloth\", # True or \"unsloth\" for very long context\n",
" random_state = 3407,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "21422429",
"metadata": {},
"outputs": [],
"source": [
"training_args = TrainingArguments(\n",
" output_dir=\"/root/models/qwen_train\",\n",
" num_train_epochs=3,\n",
" per_device_train_batch_size=1,\n",
" gradient_accumulation_steps=16,\n",
" gradient_checkpointing=True,\n",
" learning_rate=2e-5,\n",
" lr_scheduler_type=\"cosine\",\n",
" warmup_ratio=0.05,\n",
" weight_decay=0.01,\n",
" fp16=not is_bfloat16_supported(),\n",
" bf16=is_bfloat16_supported(),\n",
" logging_steps=10,\n",
" save_steps=200,\n",
" save_total_limit=3,\n",
" report_to=\"none\",\n",
" optim=\"adamw_8bit\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "83be036e",
"metadata": {},
"outputs": [],
"source": [
"trainer = SFTTrainer(\n",
" model=model,\n",
" tokenizer=tokenizer,\n",
" args=training_args,\n",
" train_dataset=dataset.to_transformers_dataset(tokenizer),\n",
" dataset_text_field=\"messages\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "886ba936",
"metadata": {},
"outputs": [],
"source": [
"trainer.train()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "13071f43",
"metadata": {},
"outputs": [],
"source": [
"model.save_pretrained_merged(\n",
" \"/root/models/qwen_merged_4bit\", \n",
" tokenizer=tokenizer,\n",
" save_method=\"merged_4bit_forced\"\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a80162e1",
"metadata": {},
"outputs": [],
"source": [
"%pip install vllm"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9a934ce7",
"metadata": {},
"outputs": [],
"source": [
"%vllm serve /root/models/qwen_merged_4bit --enable-reasoning --reasoning-parser deepseek_r1"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "notebook",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,661 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"🦥 Unsloth: Will patch your computer to enable 2x faster free finetuning.\n",
"Unsloth: Failed to patch Gemma3ForConditionalGeneration.\n",
"🦥 Unsloth Zoo will now patch everything to make training faster!\n",
"INFO 04-23 16:23:47 [__init__.py:239] Automatically detected platform cuda.\n"
]
}
],
"source": [
"# Unsloth should be imported before transformers to ensure all optimizations are applied.\n",
"from unsloth import FastLanguageModel, is_bfloat16_supported"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from dataclasses import dataclass\n",
"from pathlib import Path\n",
"from transformers import AutoTokenizer, TrainingArguments\n",
"from trl import SFTTrainer, DataCollatorForCompletionOnlyLM\n",
"from typing import Optional, List\n",
"import argparse\n",
"import json\n",
"import os"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"from train import qwq"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"args = qwq.Args([\"--output-dir\", \"/root/models/notebook\", \"--base-model\", \"unsloth/QwQ-32B-bnb-4bit\"])"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Validating 20 XML files...\n",
"file: /root/sia/training/clean_start/iteration_20250116_134549_655.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/clean_start/iteration_20250116_134549_655.xml\n",
"file: /root/sia/training/clean_start/iteration_20250116_134555_680.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/clean_start/iteration_20250116_134555_680.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141241_092.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141241_092.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141252_317.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141252_317.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141302_940.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141302_940.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141329_886.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141329_886.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141343_416.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141343_416.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141357_412.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141357_412.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141410_965.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141410_965.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141428_204.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141428_204.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141441_443.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141441_443.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141447_231.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141447_231.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141454_509.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141454_509.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141458_495.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141458_495.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141503_889.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141503_889.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141516_718.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141516_718.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141533_231.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141533_231.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141603_549.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141603_549.xml\n",
"file: /root/sia/training/delete_indicated_entries/iteration_20250116_141633_083.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/delete_indicated_entries/iteration_20250116_141633_083.xml\n",
"file: /root/sia/training/list_entries_to_delete/iteration_20250116_141227_271.xml\n",
"WARNING: System prompt hash mismatch in /root/sia/training/list_entries_to_delete/iteration_20250116_141227_271.xml\n",
"Validation complete. Found 20 valid files.\n"
]
}
],
"source": [
"dataset = qwq.Dataset(args.config_path)\n",
"dataset.validate()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "b72535c55d214b9da158b90ab0d3e65a",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer_config.json: 0%| | 0.00/8.14k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5b09cbc50ad94b81a25cf790b5841d75",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"vocab.json: 0%| | 0.00/2.78M [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d561672fb7e34306aada26df664e08cd",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"merges.txt: 0%| | 0.00/1.67M [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "b2fa48006e3047689ce3951347ee8d87",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer.json: 0%| | 0.00/11.4M [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "e4bb1c113f5b46dc95b90924de24aaaf",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"added_tokens.json: 0%| | 0.00/707 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "200953e14bad47a38757dd643c7bb176",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"special_tokens_map.json: 0%| | 0.00/614 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with open('/root/sia/qwq_tokenizer_config.json', 'r') as f:\n",
" tokenizer_config = json.load(f)\n",
"\n",
"tokenizer = AutoTokenizer.from_pretrained(\n",
" args.base_model,\n",
" **tokenizer_config,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"==((====))== Unsloth 2025.3.19: Fast Qwen2 patching. Transformers: 4.51.3. vLLM: 0.8.2.\n",
" \\\\ /| NVIDIA RTX 6000 Ada Generation. Num GPUs = 1. Max memory: 47.5 GB. Platform: Linux.\n",
"O^O/ \\_/ \\ Torch: 2.6.0+cu124. CUDA: 8.9. CUDA Toolkit: 12.4. Triton: 3.2.0\n",
"\\ / Bfloat16 = TRUE. FA [Xformers = 0.0.29.post2. FA2 = False]\n",
" \"-____-\" Free license: http://github.com/unslothai/unsloth\n",
"Unsloth: Fast downloading is enabled - ignore downloading bars which are red colored!\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "78af66cb4ea84a4e8dea6cb5db0a7ca2",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model.safetensors.index.json: 0%| | 0.00/280k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "8d4904d5f68941369fef4e0b67f21397",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model-00001-of-00004.safetensors: 0%| | 0.00/4.93G [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "728274cc4ab84d64ab152b22a842e1bc",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model-00002-of-00004.safetensors: 0%| | 0.00/4.96G [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "4273150dc40846008cc36d19b87e595e",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model-00003-of-00004.safetensors: 0%| | 0.00/5.00G [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "0d4ad6c3535741a2aeb454c98d04a395",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"model-00004-of-00004.safetensors: 0%| | 0.00/4.32G [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Sliding Window Attention is enabled but not implemented for `eager`; unexpected results may be encountered.\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "73f1c658797c4b73937e26c2012e2019",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Loading checkpoint shards: 0%| | 0/4 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "e926624cc8a1453aae8e0a814c3430da",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"generation_config.json: 0%| | 0.00/238 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "ee12750395cc40b2a44b99e24a52ef23",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer_config.json: 0%| | 0.00/8.14k [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "36c00f147e684cca97857e4f9539b6ed",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"vocab.json: 0%| | 0.00/2.78M [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5bf2c158111a4a5c8f434d1493c6dc98",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"merges.txt: 0%| | 0.00/1.67M [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "cb036c9083a24ba092cc2c5d57f0bd32",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"added_tokens.json: 0%| | 0.00/707 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "6fcc331064ac4c2fa67461098f82fff6",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"special_tokens_map.json: 0%| | 0.00/614 [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "7dea89c178f34e2185d7ebbac5b9f84e",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"tokenizer.json: 0%| | 0.00/11.4M [00:00<?, ?B/s]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"model, _returned_tokenizer = FastLanguageModel.from_pretrained(\n",
" model_name = args.base_model,\n",
" gpu_memory_utilization = 0.5, # Reduce if out of memory\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Unsloth 2025.3.19 patched 64 layers with 64 QKV layers, 64 O layers and 64 MLP layers.\n"
]
}
],
"source": [
"model = FastLanguageModel.get_peft_model(\n",
" model,\n",
" target_modules = [\n",
" \"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\",\n",
" \"gate_proj\", \"up_proj\", \"down_proj\",\n",
" ],\n",
" lora_dropout = 0, # Supports any, but = 0 is optimized\n",
" bias = \"none\", # Supports any, but = \"none\" is optimized\n",
" use_gradient_checkpointing = \"unsloth\", # True or \"unsloth\" for very long context\n",
" random_state = 3407,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"training_args = TrainingArguments(\n",
" output_dir=str(args.output_dir) + \"_train\",\n",
" num_train_epochs=3,\n",
" per_device_train_batch_size=1,\n",
" gradient_accumulation_steps=16,\n",
" gradient_checkpointing=True,\n",
" learning_rate=2e-5,\n",
" lr_scheduler_type=\"cosine\",\n",
" warmup_ratio=0.05,\n",
" weight_decay=0.01,\n",
" fp16=not is_bfloat16_supported(),\n",
" bf16=is_bfloat16_supported(),\n",
" logging_steps=10,\n",
" save_steps=200,\n",
" save_total_limit=3,\n",
" report_to=\"none\",\n",
" optim=\"adamw_8bit\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "0bf6b9b1d6de48688ff82a8077790f7a",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Generating train split: 0 examples [00:00, ? examples/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"num_proc must be <= 20. Reducing num_proc to 20 for dataset of size 20.\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "74e69db167224b35b381b91827ac0c30",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Unsloth: Tokenizing [\"messages\"] (num_proc=20): 0%| | 0/20 [00:00<?, ? examples/s]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"trainer = SFTTrainer(\n",
" model=model,\n",
" tokenizer=tokenizer,\n",
" args=training_args,\n",
" train_dataset=dataset.to_transformers_dataset(tokenizer),\n",
" dataset_text_field=\"messages\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"==((====))== Unsloth - 2x faster free finetuning | Num GPUs used = 1\n",
" \\\\ /| Num examples = 20 | Num Epochs = 3 | Total steps = 3\n",
"O^O/ \\_/ \\ Batch size per device = 1 | Gradient accumulation steps = 16\n",
"\\ / Data Parallel GPUs = 1 | Total batch size (1 x 16 x 1) = 16\n",
" \"-____-\" Trainable parameters = 134,217,728/32,000,000,000 (0.42% trained)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Unsloth: Will smartly offload gradients to save VRAM!\n"
]
},
{
"data": {
"text/html": [
"\n",
" <div>\n",
" \n",
" <progress value='3' max='3' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
" [3/3 01:48, Epoch 1/3]\n",
" </div>\n",
" <table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: left;\">\n",
" <th>Step</th>\n",
" <th>Training Loss</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" </tbody>\n",
"</table><p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"TrainOutput(global_step=3, training_loss=1.7701025009155273, metrics={'train_runtime': 187.628, 'train_samples_per_second': 0.32, 'train_steps_per_second': 0.016, 'total_flos': 1.41437049721344e+16, 'train_loss': 1.7701025009155273})"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"trainer.train()"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Unsloth: Merging 4bit and LoRA weights to 4bit...\n",
"This might take 5 minutes...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/root/venvs/train/lib/python3.10/site-packages/peft/tuners/lora/bnb.py:351: UserWarning: Merge lora module to 4-bit linear may get different generations due to rounding errors.\n",
" warnings.warn(\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"Unsloth: Saving tokenizer... Done.\n",
"Unsloth: Saving model... This might take 10 minutes for Llama-7b... Done.\n"
]
}
],
"source": [
"model.save_pretrained_merged(\n",
" str(args.output_dir) + \"_merged_4bit\", \n",
" tokenizer=tokenizer,\n",
" save_method=\"merged_4bit_forced\"\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "train",
"language": "python",
"name": "train"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,135 @@
#!/root/venvs/train/bin/python
"""
Fine-tuning for QwQ model
"""
# Unsloth should be imported before transformers to ensure all optimizations are applied.
from unsloth import FastLanguageModel, is_bfloat16_supported
from dataclasses import dataclass
from pathlib import Path
from transformers import AutoTokenizer, TrainingArguments
from trl import SFTTrainer
from typing import Optional, List
import argparse
import json
import os
from .dataset import Dataset
@dataclass
class Args:
def __init__(self, args: Optional[List[str]] = None):
parser = argparse.ArgumentParser(description='Train SIA model using QwQ')
parser.add_argument(
'--config',
type=Path,
default=Path('/root/sia/training/config.yaml'),
help='Path to config file'
)
parser.add_argument(
'--base-model',
type=str,
default='unsloth/QwQ-32B-bnb-4bit',
help='HuggingFace model ID for base model'
)
parser.add_argument(
'--output-dir',
type=Path,
required=True,
help='Directory to save the trained model'
)
parser.add_argument(
'--api-key',
type=str,
default=os.environ.get('SIA_HF_API_KEY'),
help='HuggingFace API key'
)
if args is None:
self.args = parser.parse_args()
else:
self.args = parser.parse_args(args)
@property
def config_path(self) -> Path:
return self.args.config
@property
def base_model(self) -> str:
return self.args.base_model
@property
def output_dir(self) -> Path:
return self.args.output_dir
@property
def api_key(self) -> str:
return self.args.api_key
def main():
args = Args()
dataset = Dataset(args.config_path)
dataset.validate()
with open('/root/sia/qwq_tokenizer_config.json', 'r') as f:
tokenizer_config = json.load(f)
tokenizer = AutoTokenizer.from_pretrained(
args.base_model,
**tokenizer_config,
)
model, _returned_tokenizer = FastLanguageModel.from_pretrained(
model_name = args.base_model,
gpu_memory_utilization = 0.5,
)
model = FastLanguageModel.get_peft_model(
model,
target_modules = [
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",
], # Remove QKVO if out of memory
lora_dropout = 0, # Supports any, but = 0 is optimized
bias = "none", # Supports any, but = "none" is optimized
use_gradient_checkpointing = "unsloth", # True or "unsloth" for very long context
random_state = 3407,
)
training_args = TrainingArguments(
output_dir=str(args.output_dir) + "_train",
num_train_epochs=3,
per_device_train_batch_size=1,
gradient_accumulation_steps=16,
gradient_checkpointing=True,
learning_rate=2e-5,
lr_scheduler_type="cosine",
warmup_ratio=0.05,
weight_decay=0.01,
fp16=not is_bfloat16_supported(),
bf16=is_bfloat16_supported(),
logging_steps=10,
save_steps=200,
save_total_limit=3,
report_to="none",
optim="adamw_8bit",
)
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
args=training_args,
train_dataset=dataset.to_transformers_dataset(tokenizer),
dataset_text_field="messages",
)
trainer.train()
model.save_pretrained_merged(
str(args.output_dir),
tokenizer=tokenizer,
save_method="merged_4bit_forced"
)
if __name__ == "__main__":
main()