vLLM چیست؟ آموزش اجرای مدل‌های زبانی و ساخت API سازگار با OpenAI

vLLM یک موتور متن‌باز و پربازده برای اجرای مدل‌های زبانی بزرگ و ارائه آن‌ها از طریق API است. در این راهنمای عملی، نصب vLLM، اجرای مدل، ساخت API سازگار با OpenAI، اتصال با پایتون، استفاده از Docker، مدیریت GPU، افزایش توان پاسخ‌گویی و تفاوت آن با Ollama و API درواره را بررسی می‌کنیم.

Share
آموزش vLLM برای اجرای مدل زبانی و ساخت API سازگار با OpenAI

اجرای یک مدل زبانی روی کامپیوتر شخصی با ارائه همان مدل به صدها کاربر هم‌زمان تفاوت زیادی دارد. ممکن است یک مدل در محیط آزمایشی به‌درستی پاسخ دهد، اما پس از اتصال به اپلیکیشن واقعی با مصرف زیاد حافظه GPU، صف طولانی درخواست‌ها، افزایش زمان پاسخ و کاهش توان عملیاتی روبه‌رو شود.

vLLM یک موتور متن‌باز برای استنتاج و سروینگ مدل‌های زبانی بزرگ است. این ابزار با هدف استفاده بهینه‌تر از حافظه، پردازش هم‌زمان درخواست‌ها و ارائه مدل از طریق API طراحی شده است.

یکی از مهم‌ترین قابلیت‌های vLLM، راه‌اندازی یک سرور سازگار با OpenAI API است. به همین دلیل، بسیاری از برنامه‌هایی که قبلاً به یک API سازگار با OpenAI متصل بوده‌اند، می‌توانند با تغییر base_url به یک سرور vLLM نیز متصل شوند.

در این مقاله یاد می‌گیریم:

  • vLLM چیست و چه مسئله‌ای را حل می‌کند؟
  • چه تفاوتی میان vLLM، Ollama، llama.cpp و API مدیریت‌شده وجود دارد؟
  • چگونه vLLM را نصب کنیم؟
  • چگونه یک مدل Hugging Face را به API تبدیل کنیم؟
  • چگونه با Python و OpenAI SDK به vLLM متصل شویم؟
  • چگونه vLLM را با Docker اجرا کنیم؟
  • برای استفاده واقعی چه تنظیمات و معیارهایی اهمیت دارند؟
  • چه زمانی اجرای مستقیم مدل منطقی است و چه زمانی استفاده از API درواره انتخاب مناسب‌تری خواهد بود؟

vLLM چیست؟

vLLM یک موتور متن‌باز برای اجرای عملیات Inference و ارائه مدل‌های زبانی بزرگ به‌صورت سرویس است.

Inference یا استنتاج به مرحله‌ای گفته می‌شود که یک مدل آموزش‌دیده، ورودی کاربر را دریافت و خروجی تولید می‌کند. برای مثال، وقتی کاربر پرسشی برای یک چت‌بات ارسال می‌کند، مدل در مرحله استنتاج پاسخ را توکن‌به‌توکن تولید می‌کند.

vLLM وظیفه آموزش مدل را بر عهده ندارد. تمرکز اصلی آن اجرای مدل آماده و پاسخ‌دادن کارآمد به درخواست‌ها است.

این پروژه ابتدا در Sky Computing Lab دانشگاه برکلی توسعه یافت و اکنون به یک پروژه متن‌باز جامعه‌محور تبدیل شده است. مستندات رسمی آن قابلیت‌هایی مانند PagedAttention، پردازش پیوسته درخواست‌ها، کش پیشوند، کوانتیزه‌سازی، خروجی استریم، اجرای توزیع‌شده و API سازگار با OpenAI را معرفی می‌کنند.

vLLM را می‌توان مانند یک لایه میان مدل و اپلیکیشن در نظر گرفت:

کاربر
  ↓
وب‌سایت یا اپلیکیشن
  ↓
Backend
  ↓
OpenAI-compatible API
  ↓
vLLM
  ↓
مدل زبانی روی GPU

اپلیکیشن مستقیماً با فایل‌های مدل، CUDA و حافظه GPU درگیر نمی‌شود. این مسئولیت‌ها در لایه vLLM مدیریت می‌شوند.

چرا اجرای مستقیم مدل برای محیط واقعی کافی نیست؟

ساده‌ترین روش اجرای یک مدل، بارگذاری آن با کتابخانه‌ای مانند Transformers و فراخوانی تابع generate است. این روش برای آزمایش، نوت‌بوک و پردازش تعداد محدودی ورودی مناسب است؛ اما در یک سرویس چندکاربره مشکلاتی ایجاد می‌کند.

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

  • درخواست‌ها را در صف قرار دهد؛
  • ورودی‌های با طول متفاوت را مدیریت کند؛
  • حافظه KV Cache را میان درخواست‌ها تخصیص دهد؛
  • خروجی را به‌صورت استریم ارسال کند؛
  • درخواست لغوشده را متوقف کند؛
  • میزان استفاده از GPU را کنترل کند؛
  • زمان انتظار و توان عملیاتی را اندازه‌گیری کند.

یک اسکریپت ساده Transformers معمولاً همه این قابلیت‌ها را آماده در اختیار توسعه‌دهنده قرار نمی‌دهد. vLLM برای مدیریت همین لایه سروینگ ساخته شده است.

مهم‌ترین قابلیت‌های vLLM

مدیریت بهینه حافظه با PagedAttention

مدل‌های زبانی هنگام تولید پاسخ، اطلاعات مربوط به توکن‌های قبلی را در بخشی از حافظه به نام KV Cache نگهداری می‌کنند. در سرویس‌های چندکاربره، KV Cache می‌تواند بخش بزرگی از حافظه GPU را مصرف کند.

PagedAttention روشی برای مدیریت این حافظه است که از ایده صفحه‌بندی حافظه در سیستم‌عامل الهام می‌گیرد. به‌جای رزرو یک بلوک پیوسته و بزرگ برای هر درخواست، حافظه در بلوک‌های کوچک‌تر مدیریت می‌شود.

نتیجه این طراحی می‌تواند کاهش اتلاف حافظه و امکان پردازش درخواست‌های بیشتر روی سخت‌افزار یکسان باشد. مقاله پژوهشی vLLM نیز بر مدیریت حافظه KV Cache با PagedAttention تمرکز دارد.

Continuous Batching

در Batch سنتی، سیستم چند درخواست را کنار هم قرار می‌دهد و تا پایان پردازش همه آن‌ها منتظر می‌ماند. مشکل اینجاست که پاسخ بعضی درخواست‌ها کوتاه و بعضی دیگر طولانی است.

در Continuous Batching، درخواست تمام‌شده از دسته خارج می‌شود و درخواست جدید می‌تواند جای آن را بگیرد. بنابراین ظرفیت پردازشی کمتر معطل طولانی‌ترین پاسخ باقی می‌ماند.

این قابلیت به‌خصوص در چت‌بات‌ها اهمیت دارد؛ زیرا طول ورودی و خروجی کاربران معمولاً یکسان نیست.

API سازگار با OpenAI

vLLM می‌تواند یک سرور HTTP با مسیرهایی مانند موارد زیر ایجاد کند:

/v1/models
/v1/completions
/v1/chat/completions
/v1/responses
/v1/embeddings

پشتیبانی دقیق هر endpoint به نوع مدل بستگی دارد. برای مثال، endpoint مربوط به Embedding باید با یک مدل embedding استفاده شود و Chat Completions به مدل دارای chat template نیاز دارد.

در نسخه جاری مستندات، vLLM از Chat Completions، Completions، Responses، Embeddings و بعضی APIهای صوتی برای مدل‌های سازگار پشتیبانی می‌کند.

پشتیبانی از خروجی استریم

در برنامه‌های تعاملی بهتر است کاربر برای تولید کامل پاسخ منتظر نماند. vLLM می‌تواند توکن‌ها را هنگام تولید به کلاینت ارسال کند.

این رفتار باعث می‌شود پاسخ به‌تدریج در رابط کاربری نمایش داده شود؛ مشابه تجربه کار با چت‌بات‌های آنلاین.

کوانتیزه‌سازی مدل

Quantization یا کوانتیزه‌سازی دقت عددی وزن‌های مدل را کاهش می‌دهد تا مدل فضای کمتری در حافظه اشغال کند.

vLLM از قالب‌های متنوعی مانند AWQ، GPTQ، FP8، INT8، INT4 و GGUF پشتیبانی می‌کند؛ اما سازگاری هر روش با سخت‌افزار متفاوت است. برای مثال، پشتیبانی یک روش روی GPUهای NVIDIA الزاماً به معنای پشتیبانی آن روی AMD، Intel یا CPU نیست. پیش از انتخاب فایل کوانتیزه باید جدول سازگاری نسخه جاری مستندات بررسی شود.

کوانتیزه‌سازی همیشه بدون هزینه نیست. کاهش حافظه ممکن است با یکی از نتایج زیر همراه شود:

  • افت محدود کیفیت؛
  • تغییر سرعت نسبت به مدل و سخت‌افزار؛
  • محدودشدن بعضی قابلیت‌ها؛
  • نیاز به kernel یا معماری سخت‌افزاری مشخص.

بهترین روش، مقایسه چند پیکربندی روی داده و سخت‌افزار واقعی پروژه است.

اجرای مدل روی چند GPU

اگر مدل در حافظه یک GPU جا نشود، می‌توان وزن‌های آن را میان چند GPU تقسیم کرد. این روش معمولاً با Tensor Parallelism انجام می‌شود.

برای مثال:

vllm serve <MODEL_ID> \
  --tensor-parallel-size 2

در این مثال، اجرای مدل میان دو GPU تقسیم می‌شود.

Data Parallelism کاربرد متفاوتی دارد. در آن چند نسخه از مدل برای پردازش گروه‌های مستقل درخواست اجرا می‌شوند. vLLM امکان ترکیب روش‌های موازی‌سازی را نیز فراهم می‌کند. برای مثال، مستندات رسمی نمونه‌ای با چهار گروه Data Parallel و دو GPU برای Tensor Parallel در هر گروه ارائه می‌کنند.

تفاوت vLLM با Ollama چیست؟

vLLM و Ollama هر دو امکان اجرای مدل‌های زبانی را فراهم می‌کنند، اما برای نیازهای متفاوتی مناسب‌اند.

معیارvLLMOllama
کاربرد اصلیسروینگ پربازده و چندکاربرهاجرای ساده مدل روی سیستم شخصی
راه‌اندازیتخصصی‌ترساده‌تر
محیط هدفسرور، GPU و محیط تولیددسکتاپ، توسعه و آزمایش
مدیریت درخواست هم‌زمانپیشرفتهمناسب کاربردهای سبک‌تر
OpenAI-compatible APIدارددارد، با دامنه سازگاری متفاوت
اجرای توزیع‌شدهقابلیت‌های گسترده‌ترمحدودتر
تنظیمات عملکردبسیار متنوعساده‌تر
کاربر هدفتیم زیرساخت و توسعه‌دهنده AIکاربر محلی و توسعه‌دهنده

اگر می‌خواهید یک مدل را روی لپ‌تاپ نصب و آزمایش کنید، Ollama معمولاً شروع ساده‌تری است.

اگر می‌خواهید مدل را روی سرور GPU مستقر و به تعداد زیادی کاربر ارائه کنید، vLLM گزینه تخصصی‌تری محسوب می‌شود.

تفاوت vLLM با LM Studio

LM Studio یک برنامه دسکتاپ با رابط گرافیکی برای دانلود، اجرا و آزمایش مدل‌های محلی است. این ابزار برای توسعه‌دهندگانی مناسب است که می‌خواهند بدون مدیریت پیچیده محیط پایتون یا CUDA با مدل‌ها کار کنند.

vLLM بیشتر یک مؤلفه زیرساختی است. رابط اصلی آن CLI، کتابخانه پایتون و سرور API است.

به‌طور خلاصه:

  • LM Studio برای تجربه دسکتاپ و آزمایش محلی مناسب است.
  • vLLM برای سروینگ مدل روی سرور و مدیریت بار هم‌زمان مناسب‌تر است.
  • API مدیریت‌شده برای تیمی مناسب است که نمی‌خواهد مالک زیرساخت GPU باشد.

برای آشنایی با گزینه دسکتاپ می‌توانید راهنمای LM Studio را مطالعه کنید.

تفاوت vLLM با llama.cpp

llama.cpp به اجرای مدل‌ها با وابستگی کم و پشتیبانی مناسب از CPU، دستگاه‌های شخصی و قالب GGUF شهرت دارد. این پروژه برای اجرای محلی مدل‌های کوانتیزه‌شده روی سخت‌افزار مصرفی کاربرد زیادی دارد.

vLLM بیشتر برای افزایش توان عملیاتی روی شتاب‌دهنده‌ها و سروینگ چندکاربره طراحی شده است.

انتخاب میان آن‌ها به سخت‌افزار و الگوی مصرف بستگی دارد:

  • برای اجرای مدل کوچک روی لپ‌تاپ یا CPU، llama.cpp می‌تواند انتخاب مناسبی باشد.
  • برای سرویس GPU با درخواست‌های هم‌زمان، vLLM معمولاً قابلیت‌های بیشتری در اختیار تیم قرار می‌دهد.
  • برای حذف کامل مسئولیت استقرار، API مدیریت‌شده مناسب‌تر است.

پیش‌نیاز نصب vLLM

پیش از نصب باید سه مورد بررسی شوند:

  1. سیستم‌عامل و نسخه پایتون
  2. نوع و معماری سخت‌افزار
  3. میزان حافظه لازم برای مدل

مستندات جاری vLLM برای مسیر اصلی GPU، لینوکس و نسخه‌های مشخصی از Python را اعلام می‌کنند. پشتیبانی سخت‌افزاری شامل گزینه‌هایی برای NVIDIA CUDA، AMD ROCm، Intel XPU، CPU و بعضی افزونه‌های سخت‌افزاری است. پشتیبانی بومی ویندوز محدود است و برای ویندوز معمولاً WSL یا راهکارهای جامعه‌محور مطرح می‌شود.

از آنجا که الزامات با انتشار نسخه‌های جدید تغییر می‌کنند، پیش از نصب باید صفحه Installation نسخه موردنظر را بررسی کنید.

برآورد تقریبی حافظه مدل

حافظه موردنیاز فقط به تعداد پارامترها وابسته نیست. نوع داده وزن‌ها، KV Cache، طول کانتکست، تعداد درخواست‌های هم‌زمان و سربار runtime نیز اثر دارند.

یک برآورد بسیار ساده برای وزن‌های خام مدل چنین است:

حافظه وزن‌ها ≈ تعداد پارامترها × تعداد بایت هر پارامتر

برای مثال، وزن‌های یک مدل ۷ میلیارد پارامتری در FP16 به‌صورت نظری حدود ۱۴ گیگابایت فضا می‌خواهند:

7,000,000,000 × 2 bytes ≈ 14 GB

اما این عدد کل حافظه موردنیاز سروینگ نیست. حافظه KV Cache، بافرهای پردازشی و سربارهای دیگر نیز باید در نظر گرفته شوند. بنابراین مدل ۷ میلیارد پارامتری FP16 ممکن است برای اجرای قابل‌اعتماد به GPU با حافظه بیشتری نیاز داشته باشد.

در مدل‌های کوانتیزه نیز حجم فایل به‌تنهایی معیار کافی برای انتخاب GPU نیست.

نصب vLLM با uv یا pip

پروژه vLLM استفاده از uv یا pip را برای نصب ارائه می‌کند. روش دقیق باید با نوع CUDA و PyTorch سیستم هماهنگ باشد. روش عمومی نصب به شکل زیر است:

uv pip install vllm

یا:

pip install vllm

مستندات رسمی، uv را یکی از روش‌های پیشنهادی نصب معرفی می‌کنند.

پس از نصب، فرمان زیر را بررسی کنید:

vllm --help

در سرورهای واقعی بهتر است نسخه وابستگی‌ها ثابت شود:

vllm==<TESTED_VERSION>
openai==<TESTED_VERSION>

استفاده بدون کنترل از latest می‌تواند باعث تغییر رفتار پس از انتشار نسخه جدید شود.

اجرای اولین مدل با vLLM

یک مدل سازگار را از فهرست مدل‌های پشتیبانی‌شده انتخاب کنید. شناسه زیر صرفاً نمونه است و باید با مدل آزمایش‌شده پروژه جایگزین شود:

export VLLM_MODEL="<MODEL_ID>"
export VLLM_API_KEY="change-this-key"

سپس سرور را اجرا کنید:

vllm serve "$VLLM_MODEL" \
  --host 0.0.0.0 \
  --port 8000 \
  --api-key "$VLLM_API_KEY" \
  --dtype auto

سرور پس از دریافت یا بارگذاری فایل‌های مدل روی آدرس زیر در دسترس خواهد بود:

http://localhost:8000

آدرس پایه سازگار با OpenAI:

http://localhost:8000/v1

در مستندات رسمی نیز فرمان vllm serve برای اجرای مدل و ارائه API پیشنهاد شده است.

آزمایش API با cURL

ابتدا فهرست مدل‌ها را دریافت کنید:

curl http://localhost:8000/v1/models \
  -H "Authorization: Bearer $VLLM_API_KEY"

سپس یک درخواست Chat Completions ارسال کنید:

curl http://localhost:8000/v1/chat/completions \
  -H "Authorization: Bearer $VLLM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<MODEL_ID>",
    "messages": [
      {
        "role": "system",
        "content": "شما یک دستیار فارسی دقیق هستید."
      },
      {
        "role": "user",
        "content": "PagedAttention را در دو جمله توضیح بده."
      }
    ],
    "temperature": 0.2,
    "max_tokens": 200
  }'

اگر مدل Chat Template مناسب نداشته باشد، Chat Completions ممکن است خطا بدهد. در این شرایط باید یکی از این کارها انجام شود:

  • مدل instruction یا chat دیگری انتخاب شود؛
  • chat template معتبر هنگام اجرای سرور مشخص شود؛
  • از endpoint مناسب نوع مدل استفاده شود.

اتصال Python و OpenAI SDK به vLLM

یکی از مزیت‌های API سازگار، امکان استفاده از OpenAI SDK است.

ابتدا کتابخانه را نصب کنید:

pip install openai

سپس کد زیر را اجرا کنید:

import os

from openai import OpenAI


client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key=os.environ["VLLM_API_KEY"],
)

model_id = os.environ["VLLM_MODEL"]

response = client.chat.completions.create(
    model=model_id,
    temperature=0.2,
    max_tokens=300,
    messages=[
        {
            "role": "system",
            "content": "شما یک دستیار فنی فارسی هستید.",
        },
        {
            "role": "user",
            "content": "سه تفاوت REST و WebSocket را توضیح بده.",
        },
    ],
)

print(response.choices[0].message.content)

مستندات vLLM صراحتاً استفاده از OpenAI Python Client با تغییر base_url را نشان می‌دهند.

دریافت پاسخ استریم با پایتون

برای نمایش تدریجی پاسخ:

import os

from openai import OpenAI


client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key=os.environ["VLLM_API_KEY"],
)

stream = client.chat.completions.create(
    model=os.environ["VLLM_MODEL"],
    stream=True,
    messages=[
        {
            "role": "user",
            "content": "یک توضیح کوتاه درباره مدل‌های زبانی بنویس.",
        }
    ],
)

for chunk in stream:
    delta = chunk.choices[0].delta.content

    if delta:
        print(delta, end="", flush=True)

برای استفاده در وب‌اپلیکیشن می‌توان خروجی را از Backend با Server-Sent Events یا WebSocket به رابط کاربری منتقل کرد.

اجرای vLLM با Docker

Docker کمک می‌کند وابستگی‌ها و محیط اجرا قابل‌کنترل‌تر باشند. یک نمونه عمومی برای GPUهای سازگار:

docker run --gpus all \
  --ipc=host \
  -p 8000:8000 \
  -v "$HOME/.cache/huggingface:/root/.cache/huggingface" \
  vllm/vllm-openai:latest \
  --model "<MODEL_ID>" \
  --api-key "change-this-key" \
  --dtype auto

در محیط عملی بهتر است به‌جای latest از نسخه آزمایش‌شده تصویر استفاده کنید:

vllm/vllm-openai:<TESTED_VERSION>

بسته به مدل ممکن است به توکن Hugging Face، پذیرش مجوز مدل یا فضای ذخیره‌سازی بیشتری نیاز داشته باشید.

تصویر رسمی Docker vLLM کتابخانه‌های سازگاری موردنیاز برای اجرای CUDA را فراهم می‌کند، اما درایور و دسترسی GPU در میزبان همچنان باید درست تنظیم شده باشند.

محدودکردن مصرف حافظه GPU

یکی از گزینه‌های مهم، --gpu-memory-utilization است:

vllm serve "$VLLM_MODEL" \
  --gpu-memory-utilization 0.90

این مقدار سهم موردنظر vLLM از حافظه GPU را مشخص می‌کند. انتخاب عدد بسیار بالا می‌تواند فضای کافی برای سایر پردازش‌ها باقی نگذارد؛ عدد بیش‌ازحد پایین نیز ظرفیت KV Cache و تعداد درخواست‌های هم‌زمان را کاهش می‌دهد.

مقدار مناسب باید با آزمون بار تعیین شود.

محدودکردن طول کانتکست

مدل ممکن است از کانتکست بسیار بلندی پشتیبانی کند، اما فعال‌کردن طول حداکثری همیشه به‌صرفه نیست.

می‌توانید طول مدل را محدود کنید:

vllm serve "$VLLM_MODEL" \
  --max-model-len 8192

کانتکست بلندتر می‌تواند باعث افزایش مصرف KV Cache شود. اگر کاربرد شما فقط پیام‌های کوتاه پشتیبانی را پردازش می‌کند، فعال‌کردن کانتکست بسیار بزرگ ممکن است ظرفیت هم‌زمانی را بی‌دلیل کاهش دهد.

طول مناسب را بر اساس صدک طول ورودی‌های واقعی انتخاب کنید، نه صرفاً حداکثر اعلام‌شده مدل.

استفاده از Tensor Parallelism

برای مدلی که روی یک GPU جا نمی‌شود:

vllm serve "$VLLM_MODEL" \
  --tensor-parallel-size 2

در سروری با چهار GPU:

vllm serve "$VLLM_MODEL" \
  --tensor-parallel-size 4

بزرگ‌ترکردن تعداد GPU همیشه باعث افزایش خطی سرعت نمی‌شود. ارتباط میان GPUها، معماری مدل، نوع workload و پهنای باند اتصال در نتیجه اثر دارند.

بنابراین باید حداقل این سه حالت مقایسه شوند:

  • یک GPU و مدل کوچک‌تر یا کوانتیزه؛
  • چند GPU با Tensor Parallelism؛
  • چند replica مستقل برای افزایش تعداد درخواست‌های هم‌زمان.

نام عمومی برای مدل

ممکن است نخواهید شناسه داخلی Hugging Face در API عمومی نمایش داده شود. می‌توان مدل را با یک نام سرویس‌دهی مشخص ارائه کرد:

vllm serve "$VLLM_MODEL" \
  --served-model-name "persian-assistant"

سپس کلاینت از این نام استفاده می‌کند:

response = client.chat.completions.create(
    model="persian-assistant",
    messages=[
        {
            "role": "user",
            "content": "این پیام مشتری را خلاصه کن.",
        }
    ],
)

این روش تعویض مدل پشت API را ساده‌تر می‌کند. برای مثال، تیم می‌تواند مدل زیرساختی را تغییر دهد، اما نام persian-assistant در اپلیکیشن ثابت بماند.

معماری پیشنهادی اپلیکیشن با vLLM

بهتر است مرورگر یا اپلیکیشن موبایل مستقیماً به vLLM متصل نشود.

معماری مناسب‌تر:

flowchart TD
    A["کاربر"] --> B["وب‌سایت یا اپلیکیشن"]
    B --> C["Backend محصول"]
    C --> D["صف، سهمیه و قوانین کسب‌وکار"]
    D --> E["سرور vLLM"]
    E --> F["مدل روی GPU"]

Backend باید مسئول موارد زیر باشد:

  • احراز هویت کاربران محصول؛
  • محدودیت مصرف هر کاربر؛
  • ثبت درخواست و هزینه داخلی؛
  • کنترل طول ورودی؛
  • انتخاب مدل؛
  • مدیریت timeout و retry؛
  • اعتبارسنجی خروجی؛
  • حذف یا کنترل اقدامات غیرمجاز؛
  • اعمال قوانین قطعی کسب‌وکار.

کلید دسترسی به مدل نباید در کد JavaScript سمت مرورگر قرار گیرد.

همچنین مستندات vLLM هشدار می‌دهند که گزینه --api-key همه endpointهای سرور را پوشش نمی‌دهد. در استقرار واقعی، سرویس باید پشت reverse proxy و سیاست دسترسی مناسب قرار گیرد.

نمونه Backend با FastAPI

در این مثال، Backend پیام کاربر را دریافت و برای vLLM ارسال می‌کند.

نصب وابستگی‌ها:

pip install fastapi uvicorn openai pydantic

کد:

import os

from fastapi import FastAPI, HTTPException
from openai import APIConnectionError, APIStatusError, OpenAI
from pydantic import BaseModel, Field


app = FastAPI()

client = OpenAI(
    base_url=os.getenv(
        "AI_BASE_URL",
        "http://localhost:8000/v1",
    ),
    api_key=os.environ["AI_API_KEY"],
)

MODEL_ID = os.environ["AI_MODEL"]


class ChatRequest(BaseModel):
    message: str = Field(min_length=1, max_length=4000)


class ChatResponse(BaseModel):
    answer: str


@app.post("/api/chat", response_model=ChatResponse)
def chat(payload: ChatRequest) -> ChatResponse:
    try:
        completion = client.chat.completions.create(
            model=MODEL_ID,
            temperature=0.2,
            max_tokens=500,
            messages=[
                {
                    "role": "system",
                    "content": (
                        "شما دستیار فارسی محصول هستید. "
                        "پاسخ را دقیق، کوتاه و شفاف بنویسید."
                    ),
                },
                {
                    "role": "user",
                    "content": payload.message,
                },
            ],
        )
    except APIConnectionError as error:
        raise HTTPException(
            status_code=503,
            detail="سرویس مدل در دسترس نیست.",
        ) from error
    except APIStatusError as error:
        raise HTTPException(
            status_code=502,
            detail=f"خطای سرویس مدل: {error.status_code}",
        ) from error

    content = completion.choices[0].message.content

    if not content:
        raise HTTPException(
            status_code=502,
            detail="پاسخ معتبری از مدل دریافت نشد.",
        )

    return ChatResponse(answer=content)

اجرای API:

uvicorn app:app --host 0.0.0.0 --port 8080

در این معماری، رابط کاربری فقط endpoint زیر را می‌شناسد:

POST /api/chat

جزئیات مدل و سرور vLLM داخل Backend باقی می‌ماند.

چگونه همین برنامه را به API درواره متصل کنیم؟

کدی که با یک API سازگار با OpenAI نوشته شده است، می‌تواند با تغییر تنظیمات به API درواره متصل شود.

متغیرهای محیطی:

export AI_BASE_URL="https://api.darvareh.ir/v1"
export AI_API_KEY="YOUR_DARVAREH_API_KEY"
export AI_MODEL="YOUR_MODEL_ID"

کد Python:

import os

from openai import OpenAI


client = OpenAI(
    base_url=os.environ["AI_BASE_URL"],
    api_key=os.environ["AI_API_KEY"],
)

response = client.chat.completions.create(
    model=os.environ["AI_MODEL"],
    messages=[
        {
            "role": "system",
            "content": "شما یک دستیار فارسی دقیق هستید.",
        },
        {
            "role": "user",
            "content": "یک متن کوتاه برای معرفی محصول بنویس.",
        },
    ],
)

print(response.choices[0].message.content)

در این حالت، تیم نیازی به مدیریت موارد زیر ندارد:

  • خرید و آماده‌سازی GPU؛
  • نصب CUDA و درایورها؛
  • دانلود و نگهداری مدل؛
  • مدیریت حافظه و batching؛
  • به‌روزرسانی موتور استنتاج؛
  • ظرفیت‌سنجی سرور؛
  • خاموشی و خرابی سخت‌افزار؛
  • استقرار چند مدل روی چند زیرساخت.

توسعه‌دهنده یک کلید API، یک آدرس پایه و شناسه مدل دریافت می‌کند و هزینه بر اساس مصرف محاسبه می‌شود.

برای شروع می‌توانید مستندات API درواره و راهنمای API سازگار با OpenAI را مطالعه کنید.

طراحی برنامه‌ای که میان vLLM و درواره جابه‌جا شود

بهتر است ارائه‌دهنده مدل مستقیماً در کد برنامه ثابت نشود.

تنظیمات:

export AI_BASE_URL="http://localhost:8000/v1"
export AI_API_KEY="local-key"
export AI_MODEL="persian-assistant"

برای انتقال به درواره فقط مقادیر تغییر می‌کنند:

export AI_BASE_URL="https://api.darvareh.ir/v1"
export AI_API_KEY="YOUR_DARVAREH_API_KEY"
export AI_MODEL="YOUR_MODEL_ID"

کد مشترک:

import os

from openai import OpenAI


def create_ai_client() -> OpenAI:
    return OpenAI(
        base_url=os.environ["AI_BASE_URL"],
        api_key=os.environ["AI_API_KEY"],
        timeout=60.0,
        max_retries=2,
    )

این طراحی مزایای مهمی دارد:

  • توسعه محلی با مدل self-hosted انجام می‌شود.
  • محیط عملی می‌تواند از API مدیریت‌شده استفاده کند.
  • مهاجرت میان مدل‌ها ساده‌تر می‌شود.
  • وابستگی منطق برنامه به یک مدل کاهش می‌یابد.
  • مقایسه کیفیت و هزینه چند مدل امکان‌پذیر می‌شود.

البته سازگاری API به معنای یکسان‌بودن همه قابلیت‌ها نیست. پارامترهای اختصاصی، Tool Calling، Structured Output، ورودی چندرسانه‌ای و قالب خطا باید برای هر سرویس جداگانه آزمایش شوند.

پایش vLLM در محیط عملی

راه‌اندازی سرور پایان کار نیست. در محیط واقعی باید رفتار مدل و زیرساخت پایش شود.

vLLM مجموعه‌ای از متریک‌ها را از endpoint زیر ارائه می‌کند:

/metrics

این endpoint با Prometheus سازگار است و برای مانیتورینگ سلامت، ظرفیت و عملکرد سیستم استفاده می‌شود. مستندات vLLM متریک‌ها را به دو گروه کلی سرور و درخواست تقسیم می‌کنند.

معیارهای مهم عبارت‌اند از:

  • تعداد درخواست‌های در حال اجرا؛
  • تعداد درخواست‌های منتظر؛
  • زمان رسیدن به اولین توکن؛
  • فاصله زمانی تولید توکن‌ها؛
  • طول ورودی و خروجی؛
  • تعداد توکن پردازش‌شده؛
  • میزان استفاده از KV Cache؛
  • نرخ خطا؛
  • زمان کامل پاسخ؛
  • توان عملیاتی بر حسب توکن در ثانیه.

برای آزمایش:

curl http://localhost:8000/metrics

در استقرار حرفه‌ای می‌توان Prometheus را به این endpoint متصل و داشبورد Grafana ایجاد کرد.

تفاوت Latency و Throughput

دو معیار مهم سروینگ مدل نباید با یکدیگر اشتباه گرفته شوند.

Latency

Latency مدت‌زمان لازم برای دریافت پاسخ است. در مدل زبانی بهتر است آن را به چند معیار تقسیم کنیم:

  • زمان تا دریافت اولین توکن یا TTFT؛
  • فاصله میان توکن‌های خروجی؛
  • زمان کامل‌شدن پاسخ.

برای چت‌بات، زمان اولین توکن اهمیت زیادی دارد؛ زیرا کاربر می‌خواهد سریع احساس کند پاسخ آغاز شده است.

Throughput

Throughput میزان کاری است که سیستم در یک بازه زمانی انجام می‌دهد. برای مثال:

  • درخواست در ثانیه؛
  • توکن ورودی در ثانیه؛
  • توکن خروجی در ثانیه.

ممکن است تنظیمی throughput را افزایش دهد، اما زمان انتظار یک درخواست منفرد را بیشتر کند. به همین دلیل بهینه‌سازی باید بر اساس هدف محصول انجام شود.

چگونه vLLM را بنچمارک کنیم؟

مقایسه فقط با یک پرامپت کوتاه نتیجه قابل‌اعتمادی نمی‌دهد.

یک سناریوی آزمون مناسب باید موارد زیر را شبیه‌سازی کند:

  • توزیع واقعی طول ورودی‌ها؛
  • توزیع واقعی طول خروجی‌ها؛
  • تعداد کاربران هم‌زمان؛
  • نرخ ورود درخواست‌ها؛
  • مدل و نوع کوانتیزه‌سازی؛
  • طول کانتکست؛
  • تنظیمات sampling؛
  • الگوی استریم یا پاسخ کامل.

برای هر آزمایش ثبت کنید:

معیارهدف
TTFT صدک ۵۰تجربه معمول کاربران
TTFT صدک ۹۵وضعیت کاربران کندتر
زمان کامل پاسخمدت پایان درخواست
توکن خروجی در ثانیهسرعت تولید
درخواست موفقپایداری
خطای کمبود حافظهظرفیت واقعی
تعداد درخواست منتظرفشار صف
مصرف GPUاستفاده از سخت‌افزار

انتخاب تنظیمات فقط بر اساس میانگین می‌تواند گمراه‌کننده باشد. صدک‌های ۹۵ و ۹۹ برای کشف تجربه بد کاربران اهمیت بیشتری دارند.

انتخاب مدل مناسب برای vLLM

مدل بزرگ‌تر همیشه بهترین مدل محصول نیست. انتخاب باید با آزمایش روی داده واقعی انجام شود.

معیارهای مناسب:

  • کیفیت پاسخ فارسی؛
  • دقت در اجرای دستور؛
  • نرخ توهم؛
  • پشتیبانی از JSON؛
  • کیفیت Tool Calling؛
  • طول کانتکست لازم؛
  • حافظه موردنیاز؛
  • سرعت تولید؛
  • مجوز استفاده تجاری؛
  • پشتیبانی vLLM از معماری مدل؛
  • هزینه زیرساخت برای هر درخواست.

ممکن است یک مدل کوچک‌تر و تخصصی برای طبقه‌بندی تیکت از مدل بسیار بزرگ بهتر باشد؛ زیرا سریع‌تر، ارزان‌تر و قابل‌کنترل‌تر است.

چه زمانی vLLM انتخاب مناسبی است؟

استفاده از vLLM معمولاً زمانی منطقی است که:

  • تیم به GPU مناسب دسترسی دارد؛
  • مصرف بالا و نسبتاً قابل‌پیش‌بینی است؛
  • مدل متن‌باز مشخصی انتخاب شده است؛
  • کنترل کامل نسخه و تنظیمات مدل اهمیت دارد؛
  • تیم توان مدیریت زیرساخت را دارد؛
  • داده‌ها یا فرایند سازمان به استقرار اختصاصی نیاز دارند؛
  • به throughput بالا برای یک مدل ثابت نیاز است؛
  • هزینه مالکیت زیرساخت توجیه اقتصادی دارد.

چه زمانی API درواره انتخاب مناسب‌تری است؟

API مدیریت‌شده معمولاً زمانی مناسب‌تر است که:

  • محصول در مرحله نمونه اولیه است؛
  • میزان مصرف هنوز مشخص نیست؛
  • تیم نمی‌خواهد GPU تهیه یا مدیریت کند؛
  • دسترسی به چند مدل اهمیت دارد؛
  • تغییر مدل باید سریع انجام شود؛
  • پرداخت بر اساس مصرف مناسب‌تر از هزینه ثابت سرور است؛
  • تیم می‌خواهد روی محصول و تجربه کاربری تمرکز کند؛
  • زمان عرضه قابلیت اهمیت بالایی دارد.

در بسیاری از پروژه‌ها، معماری ترکیبی نتیجه بهتری می‌دهد. برای مثال:

  • مدل کوچک و پرتکرار روی vLLM اجرا می‌شود؛
  • وظایف پیچیده به یک مدل قوی‌تر در API درواره ارسال می‌شوند؛
  • در صورت خرابی یا اشباع سرور داخلی، درخواست به سرویس دوم هدایت می‌شود؛
  • چند مدل روی مجموعه ارزیابی ثابت مقایسه می‌شوند.

مقایسه هزینه vLLM و API مدیریت‌شده

برای تصمیم اقتصادی نباید فقط قیمت GPU را با هزینه توکن مقایسه کرد.

هزینه واقعی self-hosting شامل موارد زیر است:

هزینه کل =
GPU یا اجاره سرور
+ فضای ذخیره‌سازی
+ ترافیک
+ مانیتورینگ
+ نیروی DevOps و MLOps
+ ظرفیت بلااستفاده
+ پشتیبان‌گیری و افزونگی
+ زمان ارتقا و رفع خطا

در API مدیریت‌شده، هزینه معمولاً با مصرف افزایش می‌یابد. در self-hosting، حتی اگر درخواست کمی وجود داشته باشد، هزینه سرور روشن باقی می‌ماند.

برای مقایسه منصفانه، هزینه هر یک میلیون توکن موفق یا هر وظیفه تکمیل‌شده را اندازه بگیرید:

هزینه هر درخواست موفق =
هزینه کل زیرساخت در بازه
÷
تعداد درخواست‌های معتبر همان بازه

اگر کیفیت مدل‌ها متفاوت است، هزینه به‌تنهایی معیار کافی نیست. پاسخ ارزان اما نامعتبر ممکن است هزینه عملیاتی بیشتری به کسب‌وکار تحمیل کند.

اشتباهات رایج هنگام استفاده از vLLM

انتخاب مدل قبل از اندازه‌گیری حافظه

دانلود یک مدل بزرگ بدون محاسبه حافظه وزن‌ها، KV Cache و سربار اجرا می‌تواند به خطای کمبود حافظه منجر شود.

فعال‌کردن کانتکست بسیار بلند بدون نیاز واقعی

کانتکست طولانی ظرفیت هم‌زمانی را کاهش می‌دهد. طول ورودی باید بر اساس کاربرد واقعی تعیین شود.

اجرای مدل بدون آزمون بار

موفقیت یک درخواست نشان نمی‌دهد سیستم توان پاسخ‌گویی به صد کاربر را دارد.

قراردادن vLLM مستقیماً در اینترنت

سرور مدل بهتر است پشت Backend، reverse proxy و کنترل دسترسی قرار گیرد. گزینه داخلی API Key به‌تنهایی جایگزین معماری کامل دسترسی نیست.

ثابت‌کردن شناسه مدل در کد

شناسه مدل باید در متغیر محیطی یا سامانه تنظیمات قرار گیرد تا تغییر مدل بدون ویرایش چند بخش کد انجام شود.

مقایسه مدل‌ها با پرامپت‌های متفاوت

برای ارزیابی منصفانه باید مدل‌ها روی ورودی، تنظیمات و معیارهای یکسان مقایسه شوند.

استفاده از آخرین نسخه بدون آزمون

vLLM با سرعت بالایی توسعه پیدا می‌کند. نسخه موتور، PyTorch، CUDA، درایور و تصویر Docker باید در محیط عملی ثابت و قبل از انتشار آزمایش شوند.

فرض سازگاری کامل با همه قابلیت‌های OpenAI

عبارت OpenAI-compatible به معنای یکسان‌بودن صددرصد همه endpointها و پارامترها نیست. مستندات vLLM نیز برای برخی پارامترها محدودیت یا رفتار متفاوت ذکر می‌کنند.

مسیر پیشنهادی برای استقرار vLLM

مرحله اول: انتخاب کاربرد

یک وظیفه روشن مانند پاسخ‌گویی به پرسش، خلاصه‌سازی یا استخراج اطلاعات انتخاب کنید.

مرحله دوم: ساخت مجموعه ارزیابی

حداقل چند ده نمونه واقعی همراه با خروجی مطلوب آماده کنید.

مرحله سوم: انتخاب چند مدل

مدل‌ها را بر اساس کیفیت فارسی، حافظه، مجوز و پشتیبانی vLLM انتخاب کنید.

مرحله چهارم: اجرای تک‌کاربره

ابتدا صحت پاسخ، Chat Template و تنظیمات sampling را بررسی کنید.

مرحله پنجم: آزمون بار

تعداد کاربران هم‌زمان و طول ورودی واقعی را شبیه‌سازی کنید.

مرحله ششم: پایش

متریک‌های latency، throughput، صف و حافظه را ثبت کنید.

مرحله هفتم: اتصال از طریق Backend

vLLM را مستقیماً به رابط کاربری متصل نکنید. کنترل مصرف و قوانین محصول باید در Backend باشند.

مرحله هشتم: مقایسه با API مدیریت‌شده

همان مجموعه ارزیابی را از طریق API درواره نیز اجرا و کیفیت، هزینه و پیچیدگی عملیاتی را مقایسه کنید.

مرحله نهم: انتشار محدود

سرویس را ابتدا برای گروه کوچکی از کاربران فعال کنید.

مرحله دهم: توسعه ظرفیت

پس از مشاهده الگوی مصرف، تعداد replicaها، نوع GPU یا معماری چندمدلی را تنظیم کنید.

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

آیا vLLM رایگان است؟

کد vLLM متن‌باز و با مجوز Apache 2.0 منتشر شده است، اما اجرای آن رایگان نیست. هزینه GPU، سرور، ذخیره‌سازی، ترافیک و نگهداری زیرساخت باید محاسبه شود.

آیا vLLM خودش مدل هوش مصنوعی است؟

خیر. vLLM موتور اجرای مدل است. برای استفاده از آن باید یک مدل سازگار مانند یک مدل instruction، embedding یا چندرسانه‌ای انتخاب شود.

آیا vLLM برای آموزش مدل استفاده می‌شود؟

تمرکز vLLM روی استنتاج و سروینگ است، نه آموزش کامل مدل. آموزش، Fine-tuning و آماده‌سازی وزن‌ها معمولاً با ابزارهای دیگری انجام می‌شوند.

آیا vLLM روی CPU اجرا می‌شود؟

vLLM مسیرهایی برای اجرای CPU دارد، اما نوع مدل، سرعت موردنیاز و معماری پردازنده اهمیت دارند. برای مدل‌های بزرگ و سرویس تعاملی، شتاب‌دهنده مناسب معمولاً عملکرد بهتری ارائه می‌کند. مستندات نصب، پشتیبانی از معماری‌های مختلف CPU و GPU را جداگانه توضیح می‌دهند.

آیا vLLM روی ویندوز نصب می‌شود؟

پشتیبانی بومی ویندوز در مسیر اصلی محدود است. مستندات استفاده از WSL یا گزینه‌های جامعه‌محور را مطرح می‌کنند. برای محیط تولید، لینوکس انتخاب متداول‌تری است.

آیا vLLM از مدل‌های Hugging Face پشتیبانی می‌کند؟

بله، بسیاری از معماری‌های موجود در Hugging Face پشتیبانی می‌شوند؛ اما هر مدل الزاماً سازگار نیست. باید فهرست رسمی مدل‌های پشتیبانی‌شده، نوع معماری، tokenizer و chat template بررسی شود. مستندات جاری از پشتیبانی بیش از ۲۰۰ معماری مدل سخن می‌گویند.

آیا می‌توان OpenAI SDK را به vLLM متصل کرد؟

بله. کافی است base_url روی آدرس سرور vLLM تنظیم شود و از endpoint پشتیبانی‌شده استفاده کنید.

آیا برنامه نوشته‌شده برای vLLM به درواره متصل می‌شود؟

اگر برنامه بر اساس OpenAI SDK و قابلیت‌های مشترک نوشته شده باشد، معمولاً با تغییر base_url، کلید API و شناسه مدل قابل اتصال است. بااین‌حال، پارامترهای اختصاصی هر ارائه‌دهنده باید جداگانه آزمایش شوند.

vLLM بهتر است یا API درواره؟

هیچ پاسخ یکسانی برای همه پروژه‌ها وجود ندارد. vLLM کنترل بیشتری روی مدل و زیرساخت می‌دهد؛ در مقابل، API درواره نیاز به مدیریت GPU و استقرار مدل را کاهش می‌دهد و دسترسی به مدل‌های مختلف را از یک مسیر فراهم می‌کند.

آیا برای شروع یک استارتاپ باید GPU خرید؟

معمولاً بهتر است ابتدا ارزش محصول با API و داده واقعی آزمایش شود. خرید یا اجاره زیرساخت اختصاصی زمانی منطقی‌تر می‌شود که مصرف، مدل مناسب و اقتصاد واحد محصول مشخص شده باشند.

جمع‌بندی

vLLM یک موتور تخصصی برای اجرای مدل‌های زبانی بزرگ و ارائه آن‌ها از طریق API است. قابلیت‌هایی مانند PagedAttention، Continuous Batching، استریم، کوانتیزه‌سازی، اجرای چند GPU و API سازگار با OpenAI آن را به گزینه‌ای مهم برای سروینگ مدل‌های متن‌باز تبدیل کرده‌اند.

بااین‌حال، استفاده موفق از vLLM فقط به اجرای فرمان vllm serve محدود نمی‌شود. تیم باید ظرفیت GPU، طول کانتکست، تعداد درخواست‌های هم‌زمان، کیفیت مدل، پایش، آزمون بار و هزینه نگهداری را نیز مدیریت کند.

اگر محصول در مرحله آزمایش است یا تیم نمی‌خواهد زیرساخت مدل را مدیریت کند، استفاده از API درواره می‌تواند مسیر سریع‌تری باشد. با یک API سازگار با OpenAI، یک کلید و یک آدرس پایه می‌توان مدل‌های مختلف را آزمایش و در نرم‌افزار استفاده کرد:

https://api.darvareh.ir/v1

بهترین معماری الزاماً انتخاب همیشگی میان self-hosting و API نیست. بسیاری از تیم‌ها از رویکرد ترکیبی استفاده می‌کنند: مدل‌های ثابت و پرتکرار را روی زیرساخت اختصاصی اجرا کرده و برای وظایف پیچیده، مدل‌های متنوع یا ظرفیت اضافی از API مدیریت‌شده بهره می‌برند.

برای شروع اتصال نرم‌افزار خود به مدل‌های هوش مصنوعی، مستندات API درواره را مطالعه کنید.

مقالات مرتبط

منابع

این مقاله صرفاً با هدف آموزش و اطلاع‌رسانی تهیه شده است. پیش از استفاده عملی، مستندات رسمی سرویس‌ها و صفحه سلب مسئولیت را مطالعه کنید.

Read more