Skip to content

Commit ff5ea2c

Browse files
authored
Merge branch 'main' into sreeram/cvml-tests
2 parents 2ffe1c6 + 5a22a31 commit ff5ea2c

12 files changed

Lines changed: 229 additions & 76 deletions

File tree

.github/scripts/fetch_github_issues.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
def fetch_github_issues():
1414
"""Fetch GitHub issues from the repository"""
15-
repo = "amd/halo_playbooks"
15+
repo = "amd/playbooks"
1616
token = os.environ.get("GITHUB_TOKEN", "")
1717

1818
headers = {

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,26 @@ This is AMD's official repository of playbooks for AMD developer platforms. Each
3131
| **Running LLMs with PyTorch and AMD ROCm™ software** | Run powerful language models locally with PyTorch and ROCm |
3232
| **Running and Serving LLMs with LM Studio** | Set up LM Studio to run and serve large language models |
3333
| **Automating Workflows with n8n and Local LLMs** | Build an AI-powered news summarizer using n8n and Lemonade |
34-
| **Local LLM Coding with VSCode and Qwen3-Coder** | Use VSCode with locally-running Qwen3-Coder for private code assistance |
34+
| **Local LLM Coding with VS Code and Qwen3-Coder** | Use VS Code with locally-running Qwen3-Coder for private code assistance |
3535
| **Generating Images with ComfyUI and Z Image Turbo** | Create AI-generated images using ComfyUI with Z Image Turbo |
36+
| **Chat with LLMs in Open WebUI** | Set up Open WebUI to chat with local LLMs |
37+
| **Fine-tune LLMs with PyTorch and AMD ROCm™ software** | Fine-tune large language models using PyTorch and ROCm |
38+
| **Using Lemonade Across CPU, GPU, and NPU** | Learn how to use the Lemonade framework across CPU, GPU, and NPU |
39+
| **Optimized Fine-tuning with Unsloth** | Memory-efficient LoRA fine-tuning with Unsloth |
40+
| **Speech-to-Speech Translation** | Build a real-time speech-to-speech translation system |
3641

3742
## Coming Soon
3843

3944
| Playbook | Description |
4045
|----------|-------------|
41-
| **Chat with LLMs in Open WebUI** | Set up Open WebUI to chat with local LLMs |
42-
| **Fine-tune LLMs with PyTorch and ROCm** | Fine-tune large language models using PyTorch and ROCm |
43-
| **Using Lemonade Across CPU, GPU, and NPU** | Learn how to use the Lemonade framework across CPU, GPU, and NPU |
4446
| **Local Computer Vision with Ryzen™ AI NPU** | Build local perception capabilities using CVML SDK on Ryzen AI and ROCm |
4547
| **Clustering Two Devices with llama.cpp RPC** | Distributed inference using RPC server across two AMD devices with llama.cpp |
4648
| **Getting Started with Ollama** | Install Ollama and run LLMs locally from the terminal, desktop app, or REST API |
4749
| **Getting Started Creating Agents with GAIA** | Build and deploy AI agents using the GAIA framework |
4850
| **Fine-tuning LLMs with LLaMA-Factory** | LoRA fine-tuning of large language models using LLaMA-Factory |
4951
| **Custom GPU Kernels with PyTorch ROCm** | Write and optimize custom GPU kernels using PyTorch and ROCm |
50-
| **Optimized Fine-tuning with Unsloth** | Memory-efficient LoRA fine-tuning with Unsloth |
5152
| **Quick Start on vLLM** | Run inference and serving using vLLM |
5253
| **Clustering with RCCL** | Multi-node cluster using two AMD devices with RCCL |
53-
| **Speech-to-Speech Translation** | Build a real-time speech-to-speech translation system |
5454

5555
## AMD AI Developer Program
5656

assets/banner.png

-133 KB
Loading

playbooks/supplemental/llama-factory-finetuning/README.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
3751
pip 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

4268
LLaMA Factory depends on PyTorch. You should already have it installed per the above requirements.
4369

4470
Download 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
4775
git clone --depth 1 https://github.com/hiyouga/LlamaFactory.git
4876
cd LlamaFactory
4977
pip install -e .
5078
pip 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

5393
Having 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
112178
llamafactory-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+
=======
115205
After 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

playbooks/supplemental/llama-factory-finetuning/playbook.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,24 @@
66
"supported_platforms": {
77
"halo": [
88
"linux"
9+
],
10+
"halo_box": [
11+
"linux"
912
]
1013
},
1114
"tested_platforms": {
1215
"halo": [
1316
"linux"
1417
]
1518
},
19+
"required_platforms": {
20+
"halo": [
21+
"linux"
22+
],
23+
"halo_box": [
24+
"linux"
25+
]
26+
},
1627
"platforms": ["linux"],
1728
"difficulty": "intermediate",
1829
"isNew": false,

website/src/app/api/dashboard/playbook-test-matrix/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import path from "path";
44
import JSZip from "jszip";
55

66
const REPO_OWNER = "amd";
7-
const REPO_NAME = "halo_playbooks";
7+
const REPO_NAME = "playbooks";
88
const GITHUB_API = `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}`;
99
const WORKFLOW_FILE = "test-playbooks.yml";
1010
const PLAYBOOKS_ROOT = path.join(process.cwd(), "..", "playbooks");

website/src/app/api/runners/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NextResponse } from "next/server";
22

33
const REPO_OWNER = "amd";
4-
const REPO_NAME = "halo_playbooks";
4+
const REPO_NAME = "playbooks";
55
const GITHUB_API = `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}`;
66

77
interface GHRunner {

website/src/app/dashboard/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ function SetupGuide() {
216216
<li>
217217
Set <strong className="text-white">Repository access</strong> to{" "}
218218
<code className="bg-[#242424] px-1.5 py-0.5 rounded text-[#D4915D] text-xs">Only select repositories</code>{" "}
219-
and pick <code className="bg-[#242424] px-1.5 py-0.5 rounded text-[#D4915D] text-xs">amd/halo_playbooks</code>
219+
and pick <code className="bg-[#242424] px-1.5 py-0.5 rounded text-[#D4915D] text-xs">amd/playbooks</code>
220220
</li>
221221
<li>
222222
Under <strong className="text-white">Repository permissions</strong>, set{" "}

website/src/components/DeviceCarousel.tsx

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { useCallback } from "react";
44
import raiImg from "@/app/assets/rai.png";
55
import haloImg from "@/app/assets/halo.png";
66
import radeonImg from "@/app/assets/radeon.png";
7-
import { COMING_SOON_CATEGORIES } from "@/types/playbook";
87

98
const families = [
109
{ id: "reference", name: "AMD Ryzen\u2122 AI Halo", img: haloImg },
@@ -41,34 +40,24 @@ export default function DeviceCarousel({
4140
{/* Device Family Tabs */}
4241
<div className="flex justify-center mb-8">
4342
<div className="inline-flex items-center bg-[#1a1a1a] border border-[#333333] rounded-xl p-1.5 gap-1">
44-
{families.map((family) => {
45-
const comingSoon = COMING_SOON_CATEGORIES.has(family.id);
46-
return (
47-
<button
48-
key={family.id}
49-
onClick={() => selectFamily(family.id)}
50-
className={`relative px-5 py-2.5 rounded-lg text-sm font-medium transition-all duration-300 flex flex-col items-center gap-0.5 ${
51-
activeId === family.id
52-
? "text-black shadow-lg"
53-
: "text-[#a0a0a0] hover:text-white hover:bg-[#242424]"
54-
}`}
55-
style={
56-
activeId === family.id
57-
? { backgroundColor: ACCENT }
58-
: undefined
59-
}
60-
>
61-
{family.name}
62-
{comingSoon && (
63-
<span className={`text-[9px] font-medium leading-none tracking-wide ${
64-
activeId === family.id ? "text-black/60" : "text-[#D4915D]/70"
65-
}`}>
66-
Coming Soon
67-
</span>
68-
)}
69-
</button>
70-
);
71-
})}
43+
{families.map((family) => (
44+
<button
45+
key={family.id}
46+
onClick={() => selectFamily(family.id)}
47+
className={`relative px-5 py-2.5 rounded-lg text-sm font-medium transition-all duration-300 flex flex-col items-center gap-0.5 ${
48+
activeId === family.id
49+
? "text-black shadow-lg"
50+
: "text-[#a0a0a0] hover:text-white hover:bg-[#242424]"
51+
}`}
52+
style={
53+
activeId === family.id
54+
? { backgroundColor: ACCENT }
55+
: undefined
56+
}
57+
>
58+
{family.name}
59+
</button>
60+
))}
7261
<button
7362
onClick={() => selectFamily(ALL_ID)}
7463
className={`relative px-5 py-2.5 rounded-lg text-sm font-medium transition-all duration-300 ${

0 commit comments

Comments
 (0)