はじめに
いいPCを買ってしまいました。
嬉々としてスペック自慢できるタスクを回しています。
今回はGPT-OSS-20bがRTX5090環境でどのくらい爆速になるのか見てみました。
ついでに、極めて楽にvLLMでgpt-oss-20bを動かすdocker-composeも置いておきます。
生成系AIはもうDockerで完結するものしか使いたくないのよね。
docker-compose例
webuiも一緒に動かせるようにしているよ。
オプションとか詳細は自分で確認してね。
docker-compose.yaml
services:
vllm:
image: vllm/vllm-openai:latest
container_name: vllm-server
restart: always
ipc: host
ports:
- "8000:8000"
volumes:
- ./vllm_cache:/root/.cache/huggingface
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
command: >
--model openai/gpt-oss-20b
--gpu-memory-utilization 0.90
--max-model-len 4096
open-webui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
restart: always
ports:
- "3000:8080"
environment:
- OPENAI_API_BASE_URL=http://vllm:8000/v1
- OPENAI_API_KEY=unused
- WEBUI_AUTH=False
volumes:
- open-webui:/app/backend/data
depends_on:
- vllm
volumes:
open-webui:
docker logs -f vllm-serverでログ見てれば、そのうちモデルのダウンロードが終わります。
vLLMは賢いので、GPUのVRAM32GB全てを使い果たして、速度を限界まで出してくれるようです。
vLLMのベンチマーク測定方法
どうやら、vLLMはベンチマークを測定する専用のコマンドを提供しているようです。
上で立ち上げたコンテナに対し、以下のコマンドを投げれば測定してくれます。
docker exec -it vllm-server vllm bench serve \
--model openai/gpt-oss-20b \
--dataset-name random \
--num-prompts 50 \
--random-input-len 512 \
--random-output-len 1024
ここで、モデルはすでにロードされているものを明示的に指定。
あとは、並行して投げるプロンプトの数と、入出力トークン数を指定すれば測定してくれます。
ollamaのverboseよりもちょっと充実した結果を出してくれそうです。いいね。
測定結果!
さて、本題。
測定結果を示します。
二パターン測定していて、
- Num-prompt=1, Input Len=512, Output Len=1024
- Num-prompt=50, Input Len=512, Output Len=1024
それぞれで測定しています。結果は以下の表だ!
| 項目 | パターン①:単独 | パターン②:50個並列 |
|---|---|---|
| 基本項目 | ||
| Benchmark duration (s) | 6.03 | 103.11 |
| Total input tokens | 512 | 25600 |
| Total generated tokens | 1024 | 51200 |
| Request throughput (req/s) | 0.17 | 0.48 |
| Output token throughput (tok/s) | 170 | 497 |
| Peak output token throughput (tok/s) | 174 | 4100 |
| Peak concurrent requests | 1 | 50 |
| Total token throughput (tok/s) | 255 | 745 |
| Time to First Token | ||
| Mean TTFT (ms): | 15 | 46887 |
| Median TTFT (ms) | 15 | 47578 |
| P99 TTFT (ms) | 15 | 85672 |
| Time per Output Token (excl. 1st token) | ||
| Mean TPOT (ms) | 5 | 54 |
| Median TPOT (ms) | 5 | 54 |
| P99 TPOT (ms) | 5 | 95 |
| Inter-token Latency | ||
| Mean ITL (ms) | 5 | 54 |
| Median ITL (ms) | 5 | 12 |
| P99 ITL (ms) | 5 | 60 |
正直よくわからない指標も多いですが・・・いくつかピックアップしてみてみよう。
Request throughput (req/s)
単独のプロンプトの時は0.17、50個並列の時は0.48。並列で投げるほうが、バッチ処理で効率はいいのかな?
Output token throughput
最も大事な指標の1つ。出力がどのくらい早いか。
リクエスト単独の時は167、50個並列の時は約500!
正直、167 Token/sの時点でもWebUIで見ると爆速です。文句なし!
Time To First Token (TTFT)
最も大事な指標の1つ。最初の一文字までどのくらい時間がかかるか。
並列だと、処理自体はトータルで早くても、最初の一文字がマジで遅いみたいね。
まあ、個人で使う分には並列で投げるなんてエージェントでも組まないとあまりないだろうし、そこはOK。
肝心の単独でプロンプト投げた時は15msって出てるけど、これがどのくらい信頼できるかは正直微妙。思考過程が必要なチャットなら、普通のプロンプトでも数秒考えることはままある印象なので、そこが実際はドミナントな遅延要素になる気がしますね。
Time per Output Token (excl. 1st token)
最も大事な指標の1つ?
出力が始まった後にどのくらいの速度で出力するか。
並列のほうは、まあ並列な分順当に1プロンプト当たりの速度は減少しています。
単独のほうは、いったん出力が始まると爆速で応答が画面に埋まっていきます。
感想
いやあ、思ったより爆速でしたね。
これなら、何かしらのフローの中にも組み込めそうな気がします。
思考が組み込まれているのがどうも少し速度的に安定性に欠けるかもしれませんが。
あと、相変わらずポリシーでガチガチなのはちょっと残念。
ローカルなんだから別になにしたって良いじゃないの・・・

コメント