@@ -21,6 +21,20 @@ This playbook teaches you how to fine-tune LLMs using LLaMA Factory on your loca
2121
2222## Setting up the Environment
2323
24+ <!-- @os:linux -->
25+ <!-- @test:id=create-venv timeout=120 hidden=True -->
26+ ``` bash
27+ sudo apt update
28+ sudo apt install -y python3-venv
29+ python3 -m venv venv
30+ source venv/bin/activate
31+ python3 --version
32+ pip --version
33+ ```
34+ <!-- @test:end -->
35+ <!-- @setup:id=activate-venv command="source venv/bin/activate" -->
36+ <!-- @os:end -->
37+
2438### Installing Basic Dependencies
2539
2640<!-- @os:linux -->
@@ -37,18 +51,44 @@ This playbook teaches you how to fine-tune LLMs using LLaMA Factory on your loca
3751pip install huggingface_hub
3852```
3953
54+ <<<<<<< sreeram/llama-factory-ft_tests
55+ <!-- @os:linux -->
56+ <!-- @test:id=install-deps timeout=300 hidden=True setup=activate-venv -->
57+ ``` bash
58+ python3 -m pip install --upgrade pip
59+ python3 -m pip install huggingface_hub
60+ ```
61+ <!-- @test:end -->
62+ <!-- @os:end -->
63+
64+ =======
65+ >>>>>>> main
4066### Install LLaMA Factory
4167
4268LLaMA Factory depends on PyTorch. You should already have it installed per the above requirements.
4369
4470Download the source code from [ LLaMA Factory official GitHub repository] ( https://github.com/hiyouga/LlamaFactory ) , and install its dependencies.
4571
72+ <!-- @os:linux -->
73+ <!-- @test:id=install-llamafactory timeout=900 setup=activate-venv -->
4674``` bash
4775git clone --depth 1 https://github.com/hiyouga/LlamaFactory.git
4876cd LlamaFactory
4977pip install -e .
5078pip install -r requirements/metrics.txt
5179```
80+ <!-- @test:end -->
81+ <!-- @os:end -->
82+
83+ <!-- @os:linux -->
84+ <!-- @test:id=verify-llamafactory-cli timeout=60 hidden=True setup=activate-venv -->
85+ ``` bash
86+ cd LlamaFactory
87+ llamafactory-cli version || python -m llamafactory.cli version || true
88+ command -v llamafactory-cli
89+ ```
90+ <!-- @test:end -->
91+ <!-- @os:end -->
5292
5393Having successfully installed LLaMA Factory, let's run fine-tuning on it.
5494
@@ -73,6 +113,32 @@ LLaMA Factory supports multiple fine-tuning schemes.
73113| LoRA fine-tuning | [ examples/train_lora] ( https://github.com/hiyouga/LlamaFactory/tree/main/examples/train_lora ) |
74114| QLoRA fine-tuning | [ examples/train_qlora] ( https://github.com/hiyouga/LlamaFactory/tree/main/examples/train_qlora ) |
75115
116+ <<<<<<< sreeram/llama-factory-ft_tests
117+ <!-- @os:linux -->
118+ <!-- @test:id=verify-llamafactory-files timeout=60 hidden=True setup=activate-venv -->
119+ ``` python
120+ import os
121+ import sys
122+
123+ base = " LlamaFactory"
124+ required = [
125+ " examples/train_lora/qwen3_lora_sft.yaml" ,
126+ " examples/inference/qwen3_lora_sft.yaml" ,
127+ " examples/merge_lora/qwen3_lora_sft.yaml" ,
128+ ]
129+
130+ missing = [p for p in required if not os.path.exists(os.path.join(base, p))]
131+ if missing:
132+ print (f " FAIL: Missing required files: { missing} " )
133+ sys.exit(1 )
134+
135+ print (" PASS: Required LLaMA Factory example files exist" )
136+ ```
137+ <!-- @test:end -->
138+ <!-- @os:end -->
139+
140+ =======
141+ >>>>>>> main
76142 These example configuration files have specified model parameters, fine-tuning method parameters, dataset parameters, evaluation parameters, and more. You can configure them according to your own needs. In this playbook, we will use [ qwen3_lora_sft.yaml] ( https://github.com/hiyouga/LlamaFactory/blob/main/examples/train_lora/qwen3_lora_sft.yaml ) .
77143
78144** Key parameters explained:**
@@ -112,12 +178,69 @@ You can run LLaMA Factory fine-tuning using the following command, which is base
112178llamafactory-cli train examples/train_lora/qwen3_lora_sft.yaml
113179```
114180
181+ <<<<<<< sreeram/llama-factory-ft_tests
182+ <!-- @os:linux -->
183+ <!-- @test:id=quick-train-llamafactory-lora timeout=1800 hidden=True setup=activate-venv -->
184+ ``` bash
185+ cd LlamaFactory
186+
187+ cp examples/train_lora/qwen3_lora_sft.yaml examples/train_lora/qwen3_lora_sft_ci.yaml
188+
189+ sed -i ' s/lora_rank: 8/lora_rank: 6/g' examples/train_lora/qwen3_lora_sft_ci.yaml || true
190+ sed -i ' s|output_dir: .*|output_dir: saves/qwen3_lora_sft_ci|g' examples/train_lora/qwen3_lora_sft_ci.yaml || true
191+ sed -i ' s/overwrite_output_dir: false/overwrite_output_dir: true/g' examples/train_lora/qwen3_lora_sft_ci.yaml || true
192+ sed -i ' s/per_device_train_batch_size: .*/per_device_train_batch_size: 1/g' examples/train_lora/qwen3_lora_sft_ci.yaml || true
193+ sed -i ' s/gradient_accumulation_steps: .*/gradient_accumulation_steps: 1/g' examples/train_lora/qwen3_lora_sft_ci.yaml || true
194+ sed -i ' s/num_train_epochs: .*/num_train_epochs: 1/g' examples/train_lora/qwen3_lora_sft_ci.yaml || true
195+ sed -i ' s/logging_steps: .*/logging_steps: 1/g' examples/train_lora/qwen3_lora_sft_ci.yaml || true
196+ sed -i ' s/save_steps: .*/save_steps: 5/g' examples/train_lora/qwen3_lora_sft_ci.yaml || true
197+
198+ llamafactory-cli train examples/train_lora/qwen3_lora_sft_ci.yaml
199+ ```
200+ <!-- @test:end -->
201+ <!-- @os:end -->
202+
203+ After running LLM finetuning, all generated outputs are stored in the "output_dir", including model checkpoint files, configuration files, and training metrics.
204+ =======
115205After running LLM fine-tuning, output files can be found in the path of ` output_dir ` , like the model checkpoint files, model configuration files, training metrics data files.
206+ >>>>>>> main
116207
117208<p align =" center " >
118209 <img src =" assets/qwen3_lora.png " alt =" Qwen3 LoRA Fine-tuning " width =" 600 " />
119210</p >
120211
212+ <!-- @os:linux -->
213+ <!-- @test:id=verify-llamafactory-train-output timeout=120 hidden=True setup=activate-venv -->
214+ ``` python
215+ import os
216+ import sys
217+ import glob
218+
219+ out_dir = " LlamaFactory/saves/qwen3_lora_sft_ci"
220+ if not os.path.isdir(out_dir):
221+ print (f " FAIL: Missing output directory: { out_dir} " )
222+ sys.exit(1 )
223+
224+ required = [
225+ " adapter_config.json" ,
226+ " trainer_state.json" ,
227+ " training_args.bin" ,
228+ ]
229+ missing = [f for f in required if not os.path.exists(os.path.join(out_dir, f))]
230+ if missing:
231+ print (f " FAIL: Missing required files: { missing} " )
232+ sys.exit(1 )
233+
234+ adapter_weights = glob.glob(os.path.join(out_dir, " adapter_model*.safetensors" )) + glob.glob(os.path.join(out_dir, " adapter_model*.bin" ))
235+ if not adapter_weights:
236+ print (" FAIL: Missing adapter weights" )
237+ sys.exit(1 )
238+
239+ print (" PASS: LLaMA Factory training output looks correct" )
240+ print (f " Found adapter weights: { adapter_weights} " )
241+ ```
242+ <!-- @test:end -->
243+ <!-- @os:end -->
121244
122245### Test the fine-tuned model
123246
@@ -150,6 +273,63 @@ The result of exporting the fine-tuned model is shown below.
150273 <img src =" assets/qwen3_export.png " alt =" Export Qwen3 Fine-Tuned model " width =" 600 " />
151274</p >
152275
276+ <!-- @os:linux -->
277+ <!-- @test:id=export-llamafactory-model timeout=1800 hidden=True setup=activate-venv -->
278+ ``` bash
279+ cd LlamaFactory
280+ pip install pyyaml
281+
282+ python - << 'PY '
283+ import yaml
284+ from pathlib import Path
285+
286+ src = Path("examples/merge_lora/qwen3_lora_sft.yaml")
287+ dst = Path("examples/merge_lora/qwen3_lora_sft_ci.yaml")
288+
289+ cfg = yaml.safe_load(src.read_text())
290+
291+ cfg["adapter_name_or_path"] = "saves/qwen3_lora_sft_ci"
292+ cfg["export_dir"] = "saves/qwen3_lora_sft_ci_merged"
293+
294+ dst.write_text(yaml.safe_dump(cfg, sort_keys=False))
295+ print(f"Wrote {dst}")
296+ PY
297+
298+ llamafactory-cli export examples/merge_lora/qwen3_lora_sft_ci.yaml
299+ ```
300+ <!-- @test:end -->
301+ <!-- @os:end -->
302+
303+ <!-- @os:linux -->
304+ <!-- @test:id=verify-llamafactory-export-output timeout=120 hidden=True setup=activate-venv -->
305+ ``` python
306+ import os
307+ import sys
308+ import glob
309+
310+ out_dir = " LlamaFactory/saves/qwen3_lora_sft_ci_merged"
311+ if not os.path.isdir(out_dir):
312+ print (f " FAIL: Missing export directory: { out_dir} " )
313+ sys.exit(1 )
314+
315+ required = [" config.json" ,]
316+ missing = [f for f in required if not os.path.exists(os.path.join(out_dir, f))]
317+ if missing:
318+ print (f " FAIL: Missing required export files: { missing} " )
319+ sys.exit(1 )
320+
321+ model_files = (
322+ glob.glob(os.path.join(out_dir, " *.safetensors" )) +
323+ glob.glob(os.path.join(out_dir, " pytorch_model*.bin" ))
324+ )
325+ if not model_files:
326+ print (" FAIL: Missing merged model weights" )
327+ sys.exit(1 )
328+
329+ print (" PASS: Exported merged model output looks correct" )
330+ ```
331+ <!-- @test:end -->
332+ <!-- @os:end -->
153333
154334## Using LLaMA Factory GUI
155335
0 commit comments