Radeon 890MでUnsloth LoRAファインチューニング → GGUF → Ollamaまで【Ubuntu 24.04】
はじめに
これまでの記事で、GTTメモリ拡張、ComfyUI、OpenClaw+Discord、OpenClaw OfficeとローカルAI環境を構築してきました。次にやりたかったのは「自分のデータでLLMをファインチューニングして、Ollamaで使う」です。
UnslothはLoRAファインチューニングを高速・省メモリで実行できるOSSです。3月にUnsloth Studioも正式リリースされてWeb UIでの操作も可能になりましたが、AMD GPUでのトレーニングはStudioではまだ非対応。コード版のUnsloth Coreなら AMD ROCm環境でもトレーニングできます。
この記事では、Radeon 890M(VRAM 1GB + GTT 24GB)というかなり特殊な環境で、Unsloth CoreによるLoRAファインチューニングからGGUF変換、Ollamaへの登録まで、一連のパイプラインを通した手順をまとめます。
環境
GPU: Radeon 890M(gfx1151、RDNA 3.5)
VRAM: 1GB + GTT 24GB
RAM: 32GB DDR5
Docker: ROCm 7.2 + PyTorch 2.11.0
Unsloth: 2026.3.17(Core版)
ベースモデル: Qwen2.5-1.5B-Instruct(4bit量子化)
Unsloth StudioとCoreの違い
Unslothには2つの使い方があります。
Studio(Web UI版) | Core(コード版) | |
|---|---|---|
操作方法 | ブラウザでポチポチ | Pythonスクリプト |
データセット作成 | PDF/CSVをアップロードするだけ | 自分でコード書く |
AMD GPUトレーニング | まだ非対応 | ROCm対応済み |
細かいパラメータ調整 | UIの範囲内 | 自由度高い |
今の環境(Radeon 890M)でトレーニングまでやるならCore版一択です。
Docker環境の準備
docker-compose.ymlにunslothサービスを追加
ComfyUIやOllamaと同じ~/local_LLM/docker-compose.ymlに追加します。
unsloth:
image: rocm/pytorch:rocm7.2_ubuntu24.04_py3.12_pytorch_release_2.9.1
container_name: ai_unsloth
devices:
- "/dev/kfd:/dev/kfd"
- "/dev/dri:/dev/dri"
security_opt:
- seccomp:unconfined
group_add:
- video
- render
environment:
- HSA_OVERRIDE_GFX_VERSION=11.5.1
volumes:
- ./data:/data
stdin_open: true
tty: true
restart: "no"networksは指定しません。docker-compose.ymlのdefaultネットワークがai_networkに設定されているので、自動的に参加します。restart: "no"にしているのは、常時起動する必要がないため。
$ cd ~/local_LLM
$ docker compose up -d unsloth
$ docker compose exec unsloth bashパッケージのインストール
コンテナ内で以下を実行します。初回のみ必要で、コンテナをdocker compose downで完全削除しない限りパッケージは残ります。
# Unsloth本体
pip install --no-deps unsloth unsloth-zoo
pip install "unsloth[amd] @ git+https://github.com/unslothai/unsloth"
# 依存パッケージ(バージョン指定が重要)
pip install huggingface_hub \
"transformers>=4.51.3,<=5.3.0" \
"datasets>=3.4.1,<4.4.0" \
"trl>=0.18.2,<=0.24.0" \
accelerate peft bitsandbytes \
sentencepiece protobuf hf_transfer wheel \
nest-asyncio pydantic tyro msgspec \
cut_cross_entropy diffusers "fsspec<=2025.9.0"
# ROCm版PyTorchを再インストール(pip依存解決で上書きされるため)
pip install torch torchvision torchaudio \
--index-url https://download.pytorch.org/whl/rocm7.2 \
--force-reinstall
# PyTorch再インストールで消えるパッケージを戻す
pip install cut_cross_entropy diffusers "fsspec<=2025.9.0"注意: 依存パッケージのインストール時に
torchがCUDA版に置き換わることがあります。最後に必ずROCm版のPyTorchを--force-reinstallで入れ直してください。
動作確認
$ python -c 'import torch; print("CUDA:", torch.cuda.is_available(), "| Device:", torch.cuda.get_device_name(0))'
CUDA: True | Device: AMD Radeon 890M
$ python -c 'from unsloth import FastLanguageModel; print("Unsloth OK")'
🦥 Unsloth: Will patch your computer to enable 2x faster free finetuning.
Unsloth OKFlash Attention 2の警告が出ますが、AMD環境では使えないため自動的にフォールバックします。トレーニングへの影響はありません。
トレーニング
トレーニングスクリプト
/data/unsloth/unsloth_train_test.pyとして保存します。
from unsloth import FastLanguageModel
from trl import SFTTrainer
from transformers import TrainingArguments
from datasets import Dataset
import torch
# 1. モデルロード(4bit量子化で省メモリ)
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "unsloth/Qwen2.5-1.5B-Instruct",
max_seq_length = 2048,
load_in_4bit = True,
)
# 2. LoRAアダプター追加
model = FastLanguageModel.get_peft_model(
model,
r = 16,
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj"],
lora_alpha = 16,
lora_dropout = 0,
bias = "none",
)
# 3. 学習データ(Qwen2.5のChatMLフォーマット × 4件)
train_data = [
{"text": "<|im_start|>user\nEFIRIOってなに?<|im_end|>\n<|im_start|>assistant\nEFIRIOは株式会社エフィリオのことです。AIフロンティア事業、レンタルサーバー、クラウドインフラ構築、Webシステム開発、ITコンサルティングを提供するIT企業です。<|im_end|>"},
# ... 他3件(技術ブログ、AI事業、開発環境について)
]
dataset = Dataset.from_list(train_data)
# 4. トレーニング設定
trainer = SFTTrainer(
model = model,
tokenizer = tokenizer,
train_dataset = dataset,
dataset_text_field = "text",
max_seq_length = 2048,
args = TrainingArguments(
per_device_train_batch_size = 1,
gradient_accumulation_steps = 1,
warmup_steps = 1,
max_steps = 10,
learning_rate = 2e-4,
bf16 = True,
logging_steps = 1,
output_dir = "/data/unsloth_test",
seed = 42,
),
)
# 5. トレーニング実行
trainer.train()トレーニング結果
==((====))== Unsloth 2026.3.17: Fast Qwen2 patching. Transformers: 5.3.0.
\\ /| AMD Radeon 890M. Num GPUs = 1. Max memory: 24.0 GB. Platform: Linux.
O^O/ \_/ \ Torch: 2.11.0+rocm7.2. ROCm Toolkit: 7.2.26015. Triton: 3.6.0
\ / Bfloat16 = TRUE. FA [Xformers = None. FA2 = False]
"-____-" Free license: http://github.com/unslothai/unsloth項目 | 値 |
|---|---|
モデル | Qwen2.5-1.5B-Instruct(4bit) |
LoRA | r=16、QKV+O層、4,358,144パラメータ(全体の0.28%) |
トレーニング | 10ステップ、6.5秒 |
Loss | 3.65 |
GPU使用量(ピーク) | 1.85 GB |
4件のデータで10ステップというテスト用の最小構成ですが、Radeon 890Mの4bit + LoRAで問題なくトレーニングが完走しました。
GGUF変換
Unslothには16bitマージ保存とGGUF変換の機能が組み込まれています。
# 16bitでマージ保存
model.save_pretrained_merged(
"/data/unsloth_test/merged_16bit",
tokenizer,
save_method = "merged_16bit",
)
# GGUF変換(Q4_K_M量子化)
model.save_pretrained_gguf(
"/data/unsloth_test/gguf",
tokenizer,
quantization_method = "q4_k_m",
)初回実行時にllama.cppが自動でインストール・ビルドされます。GGUF変換まで含めると15〜20分ほどかかります。
出力先は/data/unsloth_test/gguf_gguf/(ggufの後にさらに_ggufが付く)。以下のファイルが生成されます。
qwen2.5-1.5b-instruct.Q4_K_M.gguf— Ollamaで使うGGUFモデルModelfile— Ollama登録用のModelfile(テンプレートとパラメータ込み)
Ollamaへの登録
GGUFファイルの配置
OllamaはDockerコンテナで動いているので、Ollamaから見えるパスにGGUFファイルを置く必要があります。
# カスタムモデル用ディレクトリを作成
$ mkdir -p ~/local_LLM/data/models/custom
# GGUFファイルとModelfileをコピー
$ cp ~/local_LLM/data/unsloth_test/gguf_gguf/qwen2.5-1.5b-instruct.Q4_K_M.gguf ~/local_LLM/data/models/custom/
$ cp ~/local_LLM/data/unsloth_test/gguf_gguf/Modelfile ~/local_LLM/data/models/custom/Modelfileのパス修正
Unslothが生成するModelfileのFROMにはコンテナ内のパスが入っているので、Ollamaコンテナ内のパスに修正します。
Ollamaのボリュームマウントは./data/models:/root/.ollamaなので、customディレクトリは/root/.ollama/custom/になります。
$ sed -i 's|FROM qwen2.5-1.5b-instruct.Q4_K_M.gguf|FROM /root/.ollama/custom/qwen2.5-1.5b-instruct.Q4_K_M.gguf|' ~/local_LLM/data/models/custom/ModelfileOllamaに登録・実行
$ docker exec ai_ollama ollama create efirio-test -f /root/.ollama/custom/Modelfile
gathering model components
writing manifest
success
$ docker exec -it ai_ollama ollama run efirio-test "EFIRIOについて教えて"果たして結果は・・・
申し訳ありませんが、"EFIRIO"の詳細な情報は見つかりませんでした。これはおそらく特定の組織やプロダクト、または単に一部の文字列かもしれません。もう少し具体的な情報を提供いただければ幸いです。なんでやねん!ってなりましたが、それも当然で学習データが4件・10ステップだけなのでEFIRIOの情報は学習しきれていません。ですが、重要なのはトレーニング→GGUF変換→Ollama登録→推論のパイプライン全体が通ったことなので成功とします。
AMD環境でのハマりどころ
Flash Attention 2は使えない
AMD GPUではFlash Attention 2が利用できません。Unslothが自動的にXformers/SDPAにフォールバックするので、トレーニング自体は問題なく動きます。
Unslothの高速推論パスがAMDで動かない
トレーニング後にmodel.generate()で推論しようとすると、以下のエラーが出ます。
RuntimeError: output with shape [1, 12, 1, 128] doesn't match the broadcast shape [1, 12, 14, 128]Unslothの高速推論パスがAMD GPUと互換性がないためです。回避策はUnslothをimportしない別スクリプトで推論すること。
# 推論テスト(unsloth_inference_test.py)
# ※ Unslothをimportしないのがポイント
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
tokenizer = AutoTokenizer.from_pretrained("/data/unsloth_test/merged_16bit")
model = AutoModelForCausalLM.from_pretrained(
"/data/unsloth_test/merged_16bit",
dtype=torch.float16,
device_map="cuda",
)
inputs = tokenizer("質問文", return_tensors="pt").to("cuda")
with torch.no_grad():
outputs = model.generate(**inputs, max_new_tokens=128)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))Unslothをimportした時点でtransformersにモンキーパッチが適用されてしまうため、同一プロセス内では回避できません。
PyTorchのバージョン警告
Unslothはtorch<2.11.0を要求しますが、ROCm 7.2のPyTorchは2.11.0+rocm7.2です。マイナーバージョンの差で、実際には問題なく動作します。
pip依存解決でPyTorchがCUDA版に置き換わる
依存パッケージのインストール時に、pipがPyTorchをCUDA版(torch-2.11.0)で上書きすることがあります。必ず最後に--index-url https://download.pytorch.org/whl/rocm7.2 --force-reinstallでROCm版を入れ直してください。
merge_and_unload()が失敗する
transformers 5.3.0でmodel.merge_and_unload() + save_pretrained()を使うとNotImplementedErrorが出ます。Unsloth公式のmodel.save_pretrained_merged()を使ってください。
まとめ
Radeon 890M(VRAM 1GB + GTT 24GB)という特殊な環境でも、Unsloth CoreによるLoRAファインチューニング→GGUF変換→Ollama登録のパイプラインが完全に動作しました。
ステップ | 結果 |
|---|---|
GPU認識 | 24GB(VRAM 1GB + GTT 24GB) |
モデルロード(4bit) | 1.49 GB |
LoRAトレーニング(10ステップ) | 6.5秒、ピーク 1.85 GB |
16bitマージ保存 | 成功(約3GB) |
GGUF変換(Q4_K_M) | 成功 |
Ollama登録・実行 | 成功 |
今回は4件のデータ・10ステップのテストなので、ファインチューニングの効果は出ていません。実用するにはデータを数十〜数百件用意して、ステップ数を増やす必要があります。ただ、メモリ使用量が1.85GBに収まっているので、より大きなモデルやデータセットでも24GBの範囲内で十分やれそうです。
AMD環境ではUnslothの高速推論パスが動かない点は要注意ですが、トレーニング自体は問題なく、GGUFに変換してOllamaで使う分には全く影響ありません。
次はもう少し本格的に、Linux特化の独自LLMをこの環境で作ってみようと思います。今回のパイプラインがそのまま使えるので、あとはデータセットをどう設計するか次第ですね。



