پرش به محتوا
← همهٔ یادداشت‌ها

vLLM Omni روی GPU ابری: ساخت تصویر و فهم عکس با یک API

·۸ دقیقه مطالعه·تیم جی‌پی‌یو

یک چاقوی جیبی سوئیسی قرمز با تیغه، قیچی، سوهان، دربازکن و پیچ‌بطری بازشده به هر سو، روی پس‌زمینهٔ سفید.

اگر می‌خواهید روی GPU ابری فقط با یک موتور هم تصویر بسازید و هم مدلی را که عکس و صدا می‌فهمد پشت یک API بگذارید، vLLM Omni دقیقاً برای همین ساخته شده است. این پروژه شاخه‌ای از خانوادهٔ vLLM است که همان دستور آشنای vllm serve را به مدل‌های چندوجهی گسترش می‌دهد: مدل‌های ساخت تصویر و ویدیو، مدل‌های تبدیل متن به گفتار، و مدل‌های «همه‌چیزدان» مثل Qwen2.5-Omni که ورودی متن، تصویر، صدا و ویدیو می‌گیرند. خروجی همه‌شان از یک API سازگار با OpenAI بیرون می‌آید.

در این آموزش یک ماشین با کارت ۲۴ گیگابایتی اجاره می‌کنیم، قالب vLLM Omni را بالا می‌آوریم، مدل تصویر Z-Image-Turbo را سرو می‌کنیم و از ترمینال و پایتون تصویر می‌گیریم. در انتها هم می‌بینید مدل چندوجهی Qwen2.5-Omni چه سخت‌افزاری می‌خواهد و چطور به آن عکس بدهید و جواب متنی بگیرید. بخش اصلی حدود ۳۰ دقیقه طول می‌کشد و روی یک RTX 3090 چیزی کمتر از ۲۵ هزار تومان خرج دارد.

پیش‌نیازها

vLLM Omni چه فرقی با vLLM معمولی دارد؟

vLLM معمولی برای مدل‌هایی ساخته شده که متن می‌گیرند و متن پس می‌دهند. vLLM Omni همان زیرساخت را برمی‌دارد و دو چیز به آن اضافه می‌کند: پشتیبانی از مدل‌های انتشاری (diffusion) که تصویر و ویدیو می‌سازند، و اجرای «چندمرحله‌ای» برای مدل‌هایی که چند بخش جدا دارند؛ مثلاً یک بخش که ورودی را می‌فهمد و متن می‌نویسد، و بخشی دیگر که همان جواب را به صدا تبدیل می‌کند.

نتیجه برای شما ساده است: کافی است پرچم --omni را به دستور vllm serve اضافه کنید. فهرست مدل‌های پشتیبانی‌شده در مستندات رسمی vLLM Omni هست و از Qwen-Image و Z-Image تا Wan2.2 برای ویدیو و چند مدل تبدیل متن به گفتار را در بر می‌گیرد.

انتخاب ماشین مناسب

مدل‌های چندوجهی معمولاً از چند جزء ساخته شده‌اند و همهٔ این اجزا باید هم‌زمان در VRAM جا شوند. Z-Image-Turbo یک مدل تصویر ۶ میلیارد پارامتری است که در کنارش یک رمزگذار متن هم بارگذاری می‌شود؛ با دقت کامل، یک کارت ۲۴ گیگابایتی جای راحتی برایش دارد. کارت‌های ۱۲ و ۱۶ گیگابایتی برای این مدل تنگ‌اند و احتمال خطای کمبود حافظه بالاست.

  • پیشنهاد اقتصادی: RTX 3090 با ۲۴ گیگابایت VRAM، از حدود ۴۳ هزار تومان در ساعت (در زمان نوشتن این مطلب). برای ساخت تصویر و آزمایش API کاملاً کافی است.
  • پیشنهاد سریع: RTX 4090 با همان ۲۴ گیگابایت ولی توان پردازشی بسیار بیشتر، از حدود ۱۲۲ هزار تومان در ساعت (در زمان نوشتن این مطلب). وقتی می‌خواهید صدها تصویر پشت سر هم بگیرید، زمان هر تصویر را محسوس کم می‌کند.

فهرست کامل کارت‌ها را با فیلتر حافظه و قیمت در بازار GPU ببینید. قیمت ساعتی موقع اجاره قفل می‌شود و نوسان بعدی بازار روی هزینهٔ همان ماشین اثری ندارد.

اجاره و راه‌اندازی

در بازار کارت مورد نظر را انتخاب کنید و موقع اجاره قالب vLLM Omni را بردارید. ماشین با موتور نصب‌شده بالا می‌آید. بعد از چند دقیقه وضعیت ماشین «در حال اجرا» می‌شود.

در صفحهٔ ماشین، دستور آمادهٔ SSH، لینک Jupyter و توکن آن، دستور «تونل امن» و فهرست «پورت‌های منتشرشده» را می‌بینید که همه با یک کلیک کپی می‌شوند. دستور SSH را در ترمینال خودتان اجرا کنید و بعد از ورود، اول مطمئن شوید کارت دیده می‌شود و موتور نصب است:

nvidia-smi
pip show vllm vllm-omni

در خروجی دوم باید نسخهٔ هر دو بسته را ببینید و دو عدد اصلی و فرعی نسخه‌شان یکی باشد. اگر قالب دیگری مثل PyTorch گرفته‌اید و می‌خواهید دستی نصب کنید، مستندات رسمی این مسیر را می‌دهد:

uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install vllm==0.30.0 --torch-backend=auto
uv pip install vllm-omni==0.30.0

مرحلهٔ اول: سرو کردن مدل تصویر

سرور را داخل یک نشست tmux اجرا کنید تا با قطع شدن SSH از بین نرود:

apt-get update && apt-get install -y tmux
tmux new -s omni

حالا مدل را با پرچم --omni سرو کنید:

vllm serve Tongyi-MAI/Z-Image-Turbo --omni --port 8091

بار اول وزن‌های مدل از صفحهٔ Z-Image-Turbo در Hugging Face دانلود می‌شود که مجموعاً حدود ۳۰ گیگابایت است. چون ماشین خارج از ایران است، این دانلود با سرعت گیگابیتی روی خود ماشین انجام می‌شود و معمولاً چند دقیقه بیشتر طول نمی‌کشد؛ به اینترنت شما ربطی ندارد. وقتی پیام آماده بودن روی پورت ۸۰۹۱ را دیدید، با Ctrl+b و بعد d از tmux بیرون بیایید؛ سرور در پس‌زمینه زنده می‌ماند.

مرحلهٔ دوم: گرفتن تصویر از API

vLLM Omni برای مدل‌های تصویر همان مسیر /v1/images/generations سبک OpenAI را باز می‌کند. در یک نشست SSH دوم این دستور را بزنید:

curl -s http://localhost:8091/v1/images/generations \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "a cup of coffee on the table",
    "size": "1024x1024",
    "response_format": "b64_json",
    "seed": 42
  }' | jq -r '.data[0].b64_json' | base64 -d > coffee.png

اگر jq روی ماشین نیست، با apt-get install -y jq نصبش کنید. نتیجه فایل coffee.png با اندازهٔ ۱۰۲۴ در ۱۰۲۴ است. Z-Image-Turbo یک مدل «توربو» است، یعنی با تعداد گام کم کار می‌کند و هر تصویر روی کارت ۲۴ گیگابایتی چند ثانیه بیشتر طول نمی‌کشد. پرامپت را انگلیسی بنویسید؛ کیفیت خروجی با پرامپت انگلیسی بهتر است.

همین کار از پایتون هم شدنی است. چون API سازگار با OpenAI است، کتابخانهٔ رسمی OpenAI کافی است:

import base64
from openai import OpenAI

client = OpenAI(base_url="http://localhost:8091/v1", api_key="EMPTY")

resp = client.images.generate(
    model="Tongyi-MAI/Z-Image-Turbo",
    prompt="a red bicycle leaning on a blue wall",
    size="1024x1024",
    response_format="b64_json",
)
with open("bicycle.png", "wb") as f:
    f.write(base64.b64decode(resp.data[0].b64_json))

برای دیدن تصویرها، ساده‌ترین راه باز کردن Jupyter از صفحهٔ ماشین و کلیک روی فایل است. اگر می‌خواهید از لپ‌تاپ خودتان به API وصل شوید، دستور «تونل امن» صفحهٔ ماشین را برای پورت ۸۰۹۱ اجرا کنید تا localhost:8091 روی دستگاه خودتان همان سرور باشد.

مرحلهٔ سوم: مدلی که عکس و صدا می‌فهمد

جذاب‌ترین بخش vLLM Omni مدل‌هایی مثل Qwen2.5-Omni است: عکس، فایل صوتی یا ویدیو می‌گیرد و هم متن و هم صدا پس می‌دهد. یک نکتهٔ مهم: پیکربندی پیش‌فرض این مدل در vLLM Omni مرحله‌هایش را روی دو کارت پخش می‌کند. پس برای این بخش، در بازار ماشینی با دو کارت ۲۴ گیگابایتی پیدا کنید. سرو کردنش همان الگوی قبلی است:

vllm serve Qwen/Qwen2.5-Omni-7B --omni --port 8091

برای پرسیدن دربارهٔ یک عکس، درخواست را در قالب استاندارد چت بفرستید و با modalities بگویید فقط جواب متنی می‌خواهید؛ این کار مرحلهٔ ساخت صدا را حذف می‌کند و جواب سریع‌تر می‌رسد:

curl http://localhost:8091/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen/Qwen2.5-Omni-7B",
    "messages": [{"role": "user", "content": [
      {"type": "image_url", "image_url": {"url": "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png"}},
      {"type": "text", "text": "What is in this image?"}
    ]}],
    "modalities": ["text"]
  }'

اگر modalities را بردارید، پاسخ هم متن دارد و هم صدا. نمونه‌کدهای کامل برای فرستادن فایل صوتی و ویدیو در پوشهٔ مثال‌های مخزن رسمی هست.

اگر به مشکل خوردید

  • CUDA out of memory هنگام بالا آمدن یا ساخت تصویر: پرچم‌های --vae-use-slicing --vae-use-tiling را به دستور vllm serve اضافه کنید تا مصرف حافظهٔ مرحلهٔ آخر کم شود. اگر باز جا نشد، کارت با VRAM بیشتر اجاره کنید.
  • پرچم --omni شناخته نمی‌شود: نسخهٔ vllm و vllm-omni با هم نمی‌خوانند. با pip show vllm vllm-omni نسخه‌ها را مقایسه کنید؛ اعداد اصلی و فرعی باید یکی باشند.
  • خطای address already in use: پورت ۸۰۹۱ را فرایند دیگری گرفته است. با ss -ltnp ببینید چه چیزی روی آن است، یا سرور را روی پورت دیگری بالا بیاورید.
  • سرور با قطع شدن SSH می‌میرد: داخل tmux اجرایش نکرده‌اید. با tmux attach -t omni برگردید یا از نو داخل tmux اجرا کنید.
  • دانلود مدل نیمه‌کاره ماند: همان دستور vllm serve را دوباره بزنید؛ دانلود از همان‌جا ادامه پیدا می‌کند.

هزینه و صرفه‌جویی

بخش اصلی این آموزش، یعنی اجاره، دانلود مدل، بالا آمدن سرور و چند ده تصویر آزمایشی، روی RTX 3090 حدود نیم ساعت طول می‌کشد؛ یعنی چیزی حدود ۲۲ هزار تومان با قیمت در زمان نوشتن این مطلب. هزینه دقیقه‌ای از کیف پول کم می‌شود و ماشین متوقف‌شده هزینه‌ای ندارد.

سه عادت پول نگه می‌دارد. اول، وقتی دارید روی کد سمت کلاینت کار می‌کنید و مدل بی‌کار است، ماشین را متوقف کنید. دوم، برای آزمایش اولیه سراغ کارت گران نروید؛ RTX 3090 برای یادگیری کافی است. سوم، قبل از حذف ماشین تصویرها را دانلود کنید، چون دیسک ماشین با حذف آن پاک می‌شود و فضای ذخیره‌سازی دائمی وجود ندارد.

قدم بعدی

اگر می‌خواهید هزاران تصویر را با اسکریپت بسازید، ایده‌های ComfyUI API: ساخت هزار تصویر با اسکریپت پایتون را با همین API ترکیب کنید: یک حلقهٔ ساده در پایتون که پرامپت‌ها را از فایل می‌خواند. و اگر کار اصلی‌تان ویدیوست، ساخت ویدیو با Wan2GP روی GPU ابری رابط گرافیکی راحت‌تری دارد.

پرسش‌های متداول

vLLM Omni چیست و چه فرقی با vLLM دارد؟

vLLM Omni افزونه‌ای روی vLLM است که پشتیبانی از مدل‌های تصویر، ویدیو، صدا و مدل‌های چندوجهی را اضافه می‌کند. vLLM معمولی فقط مدل‌های متنی و بینایی‌متنی را سرو می‌کند. در عمل تنها فرق دستور، پرچم --omni است.

برای اجرای vLLM Omni چقدر VRAM لازم است؟

به مدل بستگی دارد. برای Z-Image-Turbo یک کارت ۲۴ گیگابایتی مثل RTX 3090 پیشنهاد می‌شود. Qwen2.5-Omni با پیکربندی پیش‌فرض روی دو کارت اجرا می‌شود و مدل‌های بزرگ‌تری مثل Qwen3-Omni کارت‌های دیتاسنتری می‌خواهند.

آیا vLLM Omni با کتابخانهٔ OpenAI کار می‌کند؟

بله. API آن سازگار با OpenAI است؛ کافی است base_url را به آدرس سرور خودتان بدهید و api_key را هر مقداری بگذارید. برای تصویر از images.generate و برای مدل‌های چندوجهی از chat.completions.create استفاده کنید.

آیا برای ساخت تصویر با vLLM Omni به کارت گرافیک نیاز است؟

بله، این مدل‌ها بدون GPU عملاً قابل استفاده نیستند. اگر کارت مناسب ندارید، ساده‌ترین راه اجارهٔ ساعتی یک ماشین ۲۴ گیگابایتی از بازار جی‌پی‌یو است.


تصویر کاور: «Swiss army knife open 20050612 (cropped)» اثر Jonas Bergsten، از ویکی‌مدیا کامنز، مالکیت عمومی (Public domain).