0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

vLLMをPodman使ってRadeon 890M(iGPU)で動かす

0
Posted at

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)がボトルネックのため、大量同時リクエストの恩恵は限定的
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?