From 8be139e06ae0e2f02b0cd3037dfafdbe4ba89a6c Mon Sep 17 00:00:00 2001 From: ariG23498 Date: Fri, 11 Apr 2025 17:58:55 +0530 Subject: [PATCH 1/4] add transformers backend blog post Signed-off-by: ariG23498 OK Signed-off-by: ariG23498 --- _posts/2025-04-11-transformers-backend.md | 163 ++++++++++++++++++ .../transformers-backend.png | Bin 0 -> 54763 bytes 2 files changed, 163 insertions(+) create mode 100644 _posts/2025-04-11-transformers-backend.md create mode 100644 assets/figures/transformers-backend/transformers-backend.png diff --git a/_posts/2025-04-11-transformers-backend.md b/_posts/2025-04-11-transformers-backend.md new file mode 100644 index 0000000..17eedf2 --- /dev/null +++ b/_posts/2025-04-11-transformers-backend.md @@ -0,0 +1,163 @@ +--- +layout: post +title: "Transformers backend integration in vLLM" +author: "The Hugging Face Team" +image: /assets/figures/transformers-backend/transformers-backend.png +thumbnail-img: /assets/figures/transformers-backend/transformers-backend.png +share-img: /assets/figures/transformers-backend/transformers-backend.png +--- + +The [Hugging Face Transformers library](https://huggingface.co/docs/transformers/main/en/index) +offers a flexible, unified interface to a vast ecosystem of model architectures. From research to +fine-tuning on custom dataset, transformers is the go-to toolkit for all. + +But when it comes to *deploying* these models at scale, inference speed and efficiency often take +center stage. Enter [vLLM](https://docs.vllm.ai/en/latest/), a library engineered for high-throughput +inference, pulling models from the Hugging Face Hub and optimizing them for production-ready performance. + +A recent addition to the vLLM codebase enables leveraging transformers as a backend to run models. +vLLM will therefore optimize throughput/latency on top of existing transformers architectures. +In this post, we’ll explore how vLLM leverages the transformers backend to combine **flexibility** +with **efficiency**, enabling you to deploy state-of-the-art models faster and smarter. + +## transformers and vLLM: Inference in Action + +Let’s start with a simple text generation task using the `meta-llama/Llama-3.2-1B` model to see how +these libraries stack up. + +**Infer with transformers** + +The transformers library shines in its simplicity and versatility. Using its `pipeline` API, inference is a breeze: + +```py +from transformers import pipeline + +pipe = pipeline("text-generation", model="meta-llama/Llama-3.2-1B") +result = pipe("The future of AI is") + +print(result[0]["generated_text"]) +``` + +This approach is perfect for prototyping or small-scale tasks, but it’s not optimized for high-volume +inference or low-latency deployment. + +**Infer with vLLM** + +vLLM takes a different track, prioritizing efficiency with features like `PagedAttention` +(a memory-efficient attention mechanism) and dynamic batching. Here’s the same task in vLLM: + +```py +from vllm import LLM, SamplingParams + +llm = LLM(model="meta-llama/Llama-3.2-1B") +params = SamplingParams(max_tokens=20) +outputs = llm.generate("The future of AI is", sampling_params=params) +print(f"Generated text: {outputs[0].outputs[0].text}") +``` + +vLLM’s inference is noticeably faster and more resource-efficient, especially under load. +For example, it can handle thousands of requests per second with lower GPU memory usage. + +## vLLM’s Deployment Superpower: OpenAI Compatibility + +Beyond raw performance, vLLM offers an OpenAI-compatible API, making it a drop-in replacement for +external services. Launch a server: + +```bash +vllm serve meta-llama/Llama-3.2-1B +``` + +Then query it with curl: + +```bash +curl http://localhost:8000/v1/completions \ + -H "Content-Type: application/json" \ + -d '{"model": "meta-llama/Llama-3.2-1B", "prompt": "San Francisco is a", "max_tokens": 7, "temperature": 0}' +``` + +Or use Python’s OpenAI client: + +```py +from openai import OpenAI + +client = OpenAI(api_key="EMPTY", base_url="http://localhost:8000/v1") +completion = client.completions.create( + model="meta-llama/Llama-3.2-1B", + prompt="San Francisco is a", + max_tokens=7, + temperature=0 +) +print("Completion result:", completion.choices[0].text) +``` + +This compatibility slashes costs and boosts control, letting you scale inference locally with vLLM’s optimizations. + +## Why need the transformers backend? + +The transformers library is optimized for contributions and +[addition of new models](https://huggingface.co/docs/transformers/en/add_new_model). Adding a new +model to vLLM on the other hand is a little +[more involved](https://docs.vllm.ai/en/latest/contributing/model/index.html). + +In the **ideal world**, we would be able to use the new model in vLLM as soon as it is added to +transformers. With the integration of the transformers backend, we step towards that ideal world. + +Here is the [official documentation](https://docs.vllm.ai/en/latest/models/supported_models.html#remote-code) +on how to make your transformers model compatible with vLLM for the integration to kick in. +We followed this and made `modeling_gpt2.py` compatible with the integration! You can follow the +changes in this [PR](https://github.com/huggingface/transformers/pull/36934). + +For a model already in transformers (and compatible with vLLM), this is what we would need to: + +```py +llm = LLM(model="new-transformers-model", model_impl="transformers") +``` + +> ![NOTE] +> It is not a strict necessity to add `model_impl` parameter. vLLM switches to the transformers +implementation on its own if the model is not natively supported in vLLM. + +Or for a custom model from the Hugging Face Hub: + +```py +llm = LLM(model="custom-hub-model", model_impl="transformers", trust_remote_code=True) +``` + +This backend acts as a **bridge**, marrying transformers’ plug-and-play flexibility with vLLM’s +inference prowess. You get the best of both worlds: rapid prototyping with transformers +and optimized deployment with vLLM. + +## Case Study: Helium + +[Kyutai Team’s Helium](https://huggingface.co/docs/transformers/en/model_doc/helium) is not yet supported by vLLM. You might want to run optimized inference on the model with vLLM, and this is where the transformers backend shines. + +Let’s see this in action: + +```bash +vllm serve kyutai/helium-1-preview-2b --model-impl transformers +``` + +Query it with the OpenAI API: + +```py +from openai import OpenAI + +openai_api_key = "EMPTY" +openai_api_base = "http://localhost:8000/v1" + +client = OpenAI( + api_key=openai_api_key, + base_url=openai_api_base, +) + +completion = client.completions.create(model="kyutai/helium-1-preview-2b", prompt="What is AI?") +print("Completion result:", completion) +``` + +Here, vLLM efficiently processes inputs, leveraging the transformers backend to load +`kyutai/helium-1-preview-2b` seamlessly. Compared to running this natively in transformers, +vLLM delivers lower latency and better resource utilization. + +By pairing Transformers’ model ecosystem with vLLM’s inference optimizations, you unlock a workflow +that’s both flexible and scalable. Whether you’re prototyping a new model, deploying a custom +creation, or scaling a multimodal app, this combination accelerates your path from research to production. \ No newline at end of file diff --git a/assets/figures/transformers-backend/transformers-backend.png b/assets/figures/transformers-backend/transformers-backend.png new file mode 100644 index 0000000000000000000000000000000000000000..b57a94888539ce04b36384c4feedc32752918d92 GIT binary patch literal 54763 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 Date: Wed, 16 Apr 2025 15:53:41 +0530 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Harry Mellor <19981378+hmellor@users.noreply.github.com> Signed-off-by: ariG23498 --- _posts/2025-04-11-transformers-backend.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/2025-04-11-transformers-backend.md b/_posts/2025-04-11-transformers-backend.md index 17eedf2..002f5af 100644 --- a/_posts/2025-04-11-transformers-backend.md +++ b/_posts/2025-04-11-transformers-backend.md @@ -20,7 +20,7 @@ vLLM will therefore optimize throughput/latency on top of existing transformers In this post, we’ll explore how vLLM leverages the transformers backend to combine **flexibility** with **efficiency**, enabling you to deploy state-of-the-art models faster and smarter. -## transformers and vLLM: Inference in Action +## Transformers and vLLM: Inference in Action Let’s start with a simple text generation task using the `meta-llama/Llama-3.2-1B` model to see how these libraries stack up. @@ -92,7 +92,7 @@ print("Completion result:", completion.choices[0].text) This compatibility slashes costs and boosts control, letting you scale inference locally with vLLM’s optimizations. -## Why need the transformers backend? +## Why do we need the transformers backend? The transformers library is optimized for contributions and [addition of new models](https://huggingface.co/docs/transformers/en/add_new_model). Adding a new From 3f1d230b098e3f81048d08bac281ceda579a40c5 Mon Sep 17 00:00:00 2001 From: Aritra Roy Gosthipaty Date: Wed, 16 Apr 2025 15:54:13 +0530 Subject: [PATCH 3/4] Update _posts/2025-04-11-transformers-backend.md Co-authored-by: Harry Mellor <19981378+hmellor@users.noreply.github.com> Signed-off-by: ariG23498 OK Signed-off-by: ariG23498 --- _posts/2025-04-11-transformers-backend.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2025-04-11-transformers-backend.md b/_posts/2025-04-11-transformers-backend.md index 002f5af..4193e32 100644 --- a/_posts/2025-04-11-transformers-backend.md +++ b/_posts/2025-04-11-transformers-backend.md @@ -105,7 +105,7 @@ transformers. With the integration of the transformers backend, we step towards Here is the [official documentation](https://docs.vllm.ai/en/latest/models/supported_models.html#remote-code) on how to make your transformers model compatible with vLLM for the integration to kick in. We followed this and made `modeling_gpt2.py` compatible with the integration! You can follow the -changes in this [PR](https://github.com/huggingface/transformers/pull/36934). +changes in this [transformers pull request](https://github.com/huggingface/transformers/pull/36934). For a model already in transformers (and compatible with vLLM), this is what we would need to: From 201b7684fdc48f0b0147f50448401a11ce1ae2b4 Mon Sep 17 00:00:00 2001 From: Harry Mellor <19981378+hmellor@users.noreply.github.com> Date: Wed, 16 Apr 2025 12:29:25 +0100 Subject: [PATCH 4/4] Update _posts/2025-04-11-transformers-backend.md Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com> --- _posts/2025-04-11-transformers-backend.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/2025-04-11-transformers-backend.md b/_posts/2025-04-11-transformers-backend.md index 4193e32..272294b 100644 --- a/_posts/2025-04-11-transformers-backend.md +++ b/_posts/2025-04-11-transformers-backend.md @@ -113,9 +113,9 @@ For a model already in transformers (and compatible with vLLM), this is what we llm = LLM(model="new-transformers-model", model_impl="transformers") ``` -> ![NOTE] +> [!NOTE] > It is not a strict necessity to add `model_impl` parameter. vLLM switches to the transformers -implementation on its own if the model is not natively supported in vLLM. +> implementation on its own if the model is not natively supported in vLLM. Or for a custom model from the Hugging Face Hub: