Podmanのインストール
$ sudo apt-get update && sudo apt-get install -y podman
$ podman --version
podman version 4.9.3
vLLMコンテナイメージのpull
gfx1150対応のイメージはrocm/vllmリポジトリにある。
https://hub.docker.com/layers/rocm/vllm/rocm7.13.0_gfx1150_ubuntu24.04_py3.13_pytorch_2.10.0_vllm_0.19.1/images/sha256-1abed774b72c05089c49ad36f0b305c222362c9bdb0ae70d290c7b92ccce6b0d
$ podman pull docker.io/rocm/vllm:rocm7.13.0_gfx1150_ubuntu24.04_py3.13_pytorch_2.10.0_vllm_0.19.1
イメージの内容:
| 項目 | バージョン |
|---|---|
| ROCm | 7.13.0 |
| vLLM | 0.19.1 |
| PyTorch | 2.10.0 |
| Python | 3.13 |
| OS | Ubuntu 24.04 |
| 対応アーキテクチャ | gfx1150 |
コンテナの起動(トラブルシューティング)
試行1: 基本的なrun
$ podman run -it --rm \
--device /dev/kfd --device /dev/dri \
--network=host --ipc=host \
--group-add=video \
--cap-add=SYS_PTRACE \
--security-opt seccomp=unconfined \
-e HSA_ENABLE_SDMA=0 \
-e GPU_MAX_HW_QUEUES=4 \
docker.io/rocm/vllm:rocm7.13.0_gfx1150_ubuntu24.04_py3.13_pytorch_2.10.0_vllm_0.19.1 \
bash -c "rocminfo 2>&1 | head -5"
ROCk module is loaded
Unable to open /dev/kfd read-write: Permission denied
root is not member of "nogroup" group, the default DRM access group.
失敗: /dev/kfdにアクセスできない。コンテナ内でデバイスの所有グループを確認する。
$ podman run --rm ... bash -c "ls -ln /dev/kfd /dev/dri/renderD128; echo '---'; id"
crw-rw---- 1 65534 65534 511, 0 Sep 15 07:28 /dev/kfd
crw-rw----+ 1 65534 65534 226, 128 Sep 15 07:28 /dev/dri/renderD128
---
uid=0(root) gid=0(root) groups=0(root),44(video)
ホスト側では/dev/kfdのGIDは110(renderグループ)だが、rootless Podmanのユーザーネームスペースにより、コンテナ内では65534(nobody/nogroup)にマッピングされている。rootユーザー(GID 0)もvideoグループ(GID 44)も65534にはアクセスできない。
なお、PyTorchのHIPビルド自体は正常で、デバイスも1つ検出されている:
$ python3 -c "import torch; print(torch.version.hip); print(torch.cuda.device_count())"
7.13.99004
1
torch.cuda.is_available()がFalseを返すのは、デバイスのパーミッションエラーが原因。
試行2: --privileged
$ podman run --rm --privileged \
--device /dev/kfd --device /dev/dri \
--network=host --ipc=host \
-e HSA_ENABLE_SDMA=0 \
docker.io/rocm/vllm:rocm7.13.0_gfx1150_ubuntu24.04_py3.13_pytorch_2.10.0_vllm_0.19.1 \
bash -c "ls -ln /dev/kfd; rocminfo 2>&1 | head -3"
crw-rw---- 1 65534 65534 511, 0 Sep 15 07:28 /dev/kfd
ROCk module is loaded
Unable to open /dev/kfd read-write: Permission denied
失敗: --privilegedでもGIDマッピングは変わらないため、同じPermission denied。
試行3: --userns=keep-id + --group-add=keep-groups
ホスト側のUID/GIDをそのまま保持する方法。
$ podman run --rm --privileged \
--userns=keep-id \
--device /dev/kfd --device /dev/dri \
--network=host --ipc=host \
--group-add=keep-groups \
-e HSA_ENABLE_SDMA=0 \
docker.io/rocm/vllm:rocm7.13.0_gfx1150_ubuntu24.04_py3.13_pytorch_2.10.0_vllm_0.19.1 \
bash -c "id; ls -ln /dev/kfd; python3 -c 'import torch'"
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu)
crw-rw---- 1 65534 65534 511, 0 Sep 15 07:28 /dev/kfd
ModuleNotFoundError: No module named 'torch'
失敗: UID 1000(ubuntu)として実行されるが、パッケージはroot向けにインストールされているためtorchが見つからない。また/dev/kfdのGIDも依然65534のまま。
原因まとめ
rootless Podmanはユーザーネームスペースを使ってUID/GIDをリマッピングする。ホストのGID 110(renderグループ)はコンテナの/etc/subgidの範囲外のため65534(nobody)に変換され、コンテナ内のどのユーザーもアクセスできない。
解決策: sudo podman(rootful)
rootful Podmanはユーザーネームスペースを使わないため、GIDがそのまま保持される。
試行4: sudo podman + --group-add=render
$ sudo podman run -it --rm \
--device /dev/kfd --device /dev/dri \
--network=host --ipc=host \
--group-add=video --group-add=render \
--cap-add=SYS_PTRACE \
--security-opt seccomp=unconfined \
-e HSA_ENABLE_SDMA=0 \
-e GPU_MAX_HW_QUEUES=4 \
docker.io/rocm/vllm:rocm7.13.0_gfx1150_ubuntu24.04_py3.13_pytorch_2.10.0_vllm_0.19.1 \
bash
Error: looking up supplemental groups for container ...: Unable to find group render: no matching entries in group file
失敗: コンテナ内にrenderグループが定義されていないため、名前での指定ができない。
試行5: sudo podman + GID番号指定(成功)
グループ名の代わりにGID番号を直接指定する。
- GID 44 = video
- GID 110 = render(ホスト側の
/dev/kfdの所有グループ)
$ sudo podman run -it --rm \
--device /dev/kfd --device /dev/dri \
--network=host --ipc=host \
--group-add=44 --group-add=110 \
--cap-add=SYS_PTRACE \
--security-opt seccomp=unconfined \
-e HSA_ENABLE_SDMA=0 \
-e GPU_MAX_HW_QUEUES=4 \
docker.io/rocm/vllm:rocm7.13.0_gfx1150_ubuntu24.04_py3.13_pytorch_2.10.0_vllm_0.19.1 \
bash
groups: cannot find name for group ID 110
root@minisforum:/app#
groups: cannot find name for group ID 110は警告のみ。GID自体は付与されている。
動作確認
root@minisforum:/app# rocminfo | grep gfx
Name: gfx1150
Name: amdgcn-amd-amdhsa--gfx1150
Name: amdgcn-amd-amdhsa--gfx11-generic
root@minisforum:/app# python3 -c "import torch; print('HIP:', torch.cuda.is_available()); print('Device:', torch.cuda.get_device_name(0))"
HIP: True
Device: AMD Radeon 890M Graphics
gfx1150がネイティブ認識され、PyTorchからもHIPデバイスとしてアクセスできた。
vLLMサーバーの起動
コンテナ内でOpenAI互換APIサーバーを起動する。
root@minisforum:/app# python3 -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-1.5B-Instruct --dtype float16 --max-model-len 2048
起動ログ(抜粋):
INFO [model.py:549] Resolved architecture: Qwen2ForCausalLM
WARNING [model.py:2016] Casting torch.bfloat16 to torch.float16.
INFO [model.py:1678] Using max model len 2048
モデルのアーキテクチャを解決し、元がbfloat16のところをfloat16にキャストしている。
INFO [rocm.py:496] Using ROCM_ATTN backend out of potential backends: ['ROCM_ATTN', 'TRITON_ATTN'].
AttentionバックエンドとしてROCM_ATTNが選択された。
INFO [weight_utils.py:581] Time spent downloading weights for Qwen/Qwen2.5-1.5B-Instruct: 33.138214 seconds
INFO [default_loader.py:384] Loading weights took 0.75 seconds
INFO [gpu_model_runner.py:4820] Model loading took 3.03 GiB memory and 34.883725 seconds
Hugging Faceからのダウンロードに33秒、ウェイトのGPUメモリへのロードは0.75秒。合計3.03 GiB使用。
INFO [backends.py:390] Compiling a graph for compile range (1, 2048) takes 7.56 s
INFO [monitor.py:48] torch.compile took 10.55 s in total
torch.compileによるグラフコンパイルに10.55秒。
INFO [gpu_worker.py:436] Available KV cache memory: 37.53 GiB
INFO [kv_cache_utils.py:1319] GPU KV cache size: 1,405,648 tokens
INFO [kv_cache_utils.py:1324] Maximum concurrency for 2,048 tokens per request: 686.35x
KVキャッシュに37.53 GiB利用可能。VRAMは2GBだがGTT(64GB)が活用されている。BIOSのUMA変更は不要だった。
Capturing CUDA graphs (mixed prefill-decode, PIECEWISE): 100%|█| 51/51 [00:05<00
Capturing CUDA graphs (decode, FULL): 100%|█████| 35/35 [00:03<00:00, 11.11it/s]
INFO [gpu_model_runner.py:6046] Graph capturing finished in 10 secs, took 0.34 GiB
CUDAグラフのキャプチャに10秒、0.34 GiB使用。
INFO [core.py:283] init engine (profile, create kv cache, warmup model) took 29.16 seconds
INFO [api_server.py:596] Starting vLLM server on http://0.0.0.0:8000
エンジン初期化完了、APIサーバーがポート8000で起動。
リクエストの送信
別ターミナルからOpenAI互換APIにリクエストを送信する。
$ curl -s http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-1.5B-Instruct",
"messages": [{"role": "user", "content": "日本の首都はどこですか?"}],
"max_tokens": 100
}' | python3 -m json.tool
{
"id": "chatcmpl-9c2638e7481cfaf4",
"object": "chat.completion",
"created": 1789463125,
"model": "Qwen/Qwen2.5-1.5B-Instruct",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "日本の首都は東京です。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 35,
"total_tokens": 43,
"completion_tokens": 8
}
}
スループット
サーバーのログに出力されるスループット:
Engine 000: Avg prompt throughput: 3.4 tokens/s, Avg generation throughput: 3.2 tokens/s
Engine 000: Avg prompt throughput: 0.0 tokens/s, Avg generation throughput: 24.8 tokens/s
初回は3.2 tokens/sだが、安定時は24.8 tokens/s。
Radeon 890M(iGPU)上でvLLMが正常に動作することを確認できた。
まとめ
vLLMとOllamaの比較(同一マシン)
| vLLM | Ollama | |
|---|---|---|
| 生成速度 | 24.8 tokens/s | 67.5 tokens/s |
| 同時リクエスト | 686並列(PagedAttention + Continuous Batching) | 基本シングルリクエスト |
| API | OpenAI互換(/v1/chat/completions) |
OpenAI互換 + 独自API |
| セットアップ | Podmanコンテナ、sudoが必要 | ネイティブインストール |
使い分け
- Ollama: 単体チャット用途。速くて手軽
- vLLM: 複数クライアントからアクセスするAPIサーバー用途。同時リクエスト処理とPrefix cachingに強い
iGPU固有の知見
- VRAM 2GB(BIOS UMA設定)でもGTT 64GB(
amdgpu.gttsize=65536)が活用され、KVキャッシュ37.53 GiBが利用できた。BIOSのUMA変更は不要 - ただしiGPUの共有メモリ帯域幅(128 GB/s)がボトルネックのため、大量同時リクエストの恩恵は限定的