Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
adf4bd3
tests: Add support for unit testing within the worker processes
sangstar May 28, 2025
b349690
fix: Add a `._debug_ctx`, arbitrary serializer and deserializer kwargs
sangstar May 28, 2025
2a3375c
fix: Add `--serialization-kwargs` support to `tensorize_vllm_model.py…
sangstar May 28, 2025
2fe2570
fix: Rm pointless `._debug_ctx` attribute
sangstar May 28, 2025
66fe8aa
tests: Rm `_debug` in initializer
sangstar May 28, 2025
0dc3b6f
fix: Add test to confirm `deserialization_kwargs` passed to `TensorDe…
sangstar May 29, 2025
f85a816
fix: Add `stream_kwargs` and add test for it
sangstar May 29, 2025
6c862f5
tests: Update entrypoint test to include new kwargs, add other test
sangstar May 29, 2025
dcd5286
docs: Update md on using Tensorizer with vLLM
sangstar May 29, 2025
2b818ab
tests: Print outputs from subprocesses for test
sangstar May 29, 2025
927625a
docs: Fix link
sangstar May 29, 2025
0faa197
docs: Add more updates to md
sangstar May 29, 2025
b46b588
docs: Clarify model tensors location
sangstar May 29, 2025
b22eac1
fix: Allow parsing JSON strings with newlines
sangstar Jun 3, 2025
ca73096
tests: Confirm server starts successfully for `vllm serve` test
sangstar Jun 3, 2025
2626504
Update docs/models/extensions/tensorizer.md
sangstar Jun 10, 2025
44d25f9
Apply suggestions from code review
sangstar Jun 10, 2025
2cefde1
fix: Properly assert type for serialization/deserialization args
sangstar Jun 10, 2025
3eabef5
tests: Resolve review comments on tests
sangstar Jun 10, 2025
eaebcca
docs: Add clarifications on deprecated args, usage doc
sangstar Jun 10, 2025
b51ee42
Apply suggestions from code review
sangstar Jun 11, 2025
a0ff85b
Update docs/models/extensions/tensorizer.md
sangstar Jun 11, 2025
2a8a617
Update examples/others/tensorize_vllm_model.py
sangstar Jun 11, 2025
6127ddb
fix: Implement changes from second review
sangstar Jun 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 91 additions & 3 deletions docs/models/extensions/tensorizer.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,97 @@ vLLM model tensors that have been serialized to disk, an HTTP/HTTPS endpoint, or
at runtime extremely quickly directly to the GPU, resulting in significantly
shorter Pod startup times and CPU memory usage. Tensor encryption is also supported.
Comment thread
sangstar marked this conversation as resolved.
Outdated

For more information on CoreWeave's Tensorizer, please refer to
[CoreWeave's Tensorizer documentation](https://github.com/coreweave/tensorizer). For more information on serializing a vLLM model, as well a general usage guide to using Tensorizer with vLLM, see
the [vLLM example script](https://docs.vllm.ai/en/latest/examples/tensorize_vllm_model.html).
vLLM fully integrates Tensorizer in to its model loading machinery. The
Comment thread
sangstar marked this conversation as resolved.
Outdated
following will give a brief overview on how to get started with using
Tensorizer on vLLM.

## The basics
To load a model using Tensorizer, it first needs to be serialized by Tensorizer.
The example script in [examples/others/tensorize_vllm_model.py](https://github.com/vllm-project/vllm/blob/main/examples/others/tensorize_vllm_model.py)
takes care of this process.

The core frontend object of note integrating Tensorizer is
`TensorizerConfig`, defined [here](https://github.com/vllm-project/vllm/blob/main/vllm/model_executor/model_loader/tensorizer.py#L135-L214)
It's a config object holding important state and passed to any serialization
or deserialization operation. When loading with Tensorizer using the vLLM
Comment thread
sangstar marked this conversation as resolved.
Outdated
library rather than through a model-serving entrypoint, it gets passed to
the `LLM` entrypoint class directly. Here's an example of loading a model
saved at `"s3://my-bucket/vllm/facebook/opt-125m/v1/model.tensors"`.
Comment thread
sangstar marked this conversation as resolved.
Outdated

```python
from vllm import LLM
from vllm.model_executor.model_loader.tensorizer import TensorizerConfig

path_to_tensors = "s3://my-bucket/vllm/facebook/opt-125m/v1/model.tensors"

model_ref = "facebook/opt-125m"
tensorizer_config = TensorizerConfig(
tensorizer_uri=path_to_tensors,
)
Comment thread
sangstar marked this conversation as resolved.
Outdated

llm = LLM(
model_ref,
load_format="tensorizer",
model_loader_extra_config=tensorizer_config,
)
```

But that code won't work unless you actually have your serialized model
tensors `model.tensors`, so let's walk through a basic example of serializing
`facebook/opt-125m` using the example script, and then loading it for inference.
Comment thread
sangstar marked this conversation as resolved.
Outdated

## Saving a vLLM model with Tensorizer
To save a model with Tensorizer, call the example script with the necessary
CLI arguments. The docstring for the script itself explains the CLI args
and how to use it properly in great detail, and we'll use one of the
examples from the docstring directly, assuming we want to save our model at
our S3 bucket example `s3://my-bucket`:

```bash
python examples/others/tensorize_vllm_model.py \
--model facebook/opt-125m \
serialize \
--serialized-directory s3://my-bucket \
--suffix v1
```

This saves the model tensors at
`s3://my-bucket/vllm/facebook/opt-125m/v1/model.tensors`.

## Serving the model using Tensorizer
Once the model is serialized where you want it, you need to pass
`--load-format=tensorizer` as well as a JSON string to the
`--model-loader-extra-config` CLI arg for `vllm serve`, specifying
all the keyword arguments you'd normally pass to the `TensorizerConfig`
initializer, as if you were instantiating it like this, for instance:
`TensorizerConfig(**{"tensorizer_uri": "foo"})`. Here's an example bash
script that neatly lays out the JSON string before passing it to
`--model-loader-extra-config`:
Comment thread
sangstar marked this conversation as resolved.
Outdated

```bash
#!/bin/bash
Comment thread
sangstar marked this conversation as resolved.
Outdated

read -r -d '' JSON << EOF
{
"tensorizer_uri": "s3://my-bucket/vllm/facebook/opt-125m/v1/model.tensors",
"stream_kwargs": {"force_http": "False"},
"deserialization_kwargs": {"verify_hash": "True", "num_readers": 8}
}
EOF

MODEL_LOADER_EXTRA_CONFIG=$(echo "$JSON" | tr -d '\n')
Comment thread
sangstar marked this conversation as resolved.
Outdated

vllm serve facebook/opt-125m \
--load-format=tensorizer \
--model-loader-extra-config="$MODEL_LOADER_EXTRA_CONFIG"
```

Note in this case, if the directory to the model artifacts at
`s3://my-bucket/vllm/facebook/opt-125m/v1/` doesn't at least have a `config.
json` file, you'll want to pass `facebook/opt-125m` as the model tag like
it was done in the example script above. In our example, we just added a
Comment thread
sangstar marked this conversation as resolved.
Outdated
`model.tensors` file to that directory. In this case, vLLM will take care of
resolving the other model artifacts using HF Hub.

!!! note
Note that to use this feature you will need to install `tensorizer` by running `pip install vllm[tensorizer]`.
14 changes: 14 additions & 0 deletions examples/others/tensorize_vllm_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,14 @@ def parse_args():
"where `suffix` is given by `--suffix` or a random UUID if not "
"provided.")

serialize_parser.add_argument(
"--serialization-kwargs",
type=str,
required=False,
help=("A JSON string containing additional keyword arguments that "
"will be passed to Tensorizer's `TensorSerializer` during "
"serialization."))
Comment thread
sangstar marked this conversation as resolved.
Outdated

serialize_parser.add_argument(
"--keyfile",
type=str,
Expand Down Expand Up @@ -295,6 +303,12 @@ def deserialize():
encryption_keyfile=keyfile,
**credentials)

if args.serialization_kwargs:
serialization_kwargs = json.loads(args.serialization_kwargs)
Comment thread
sangstar marked this conversation as resolved.
Outdated
tensorizer_config.serialization_kwargs = serialization_kwargs
print("Found serialization kwargs: ", serialization_kwargs)

Comment thread
sangstar marked this conversation as resolved.
Outdated

if args.lora_path:
tensorizer_config.lora_dir = tensorizer_config.tensorizer_dir
tensorize_lora_adapter(args.lora_path, tensorizer_config)
Expand Down
10 changes: 8 additions & 2 deletions tests/entrypoints/openai/test_tensorizer_entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,18 @@ def tensorize_model_and_lora(tmp_dir, model_uri):
def server(model_uri, tensorize_model_and_lora):
model_loader_extra_config = {
"tensorizer_uri": model_uri,
"stream_kwargs": {
"force_http": False,
},
"deserialization_kwargs": {
"verify_hash": True,
"num_readers": 8,
}
}

## Start OpenAI API server
args = [
"--load-format", "tensorizer", "--device", "cuda",
"--model-loader-extra-config",
"--load-format", "tensorizer", "--model-loader-extra-config",
json.dumps(model_loader_extra_config), "--enable-lora"
]

Expand Down
4 changes: 3 additions & 1 deletion tests/lora/test_llama_tp.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
import subprocess
import sys
import json
from typing import Union

import pytest
Expand Down Expand Up @@ -210,7 +211,8 @@ def test_tp2_serialize_and_deserialize_lora(tmp_path, sql_lora_files,
f"{VLLM_PATH}/examples/others/tensorize_vllm_model.py", "--model",
MODEL_PATH, "--lora-path", lora_path, "--tensor-parallel-size",
str(tp_size), "serialize", "--serialized-directory",
str(tmp_path), "--suffix", suffix
str(tmp_path), "--suffix", suffix, "--serialization-kwargs",
json.dumps({"limit_cpu_concurrency": 4})
Comment thread
sangstar marked this conversation as resolved.
Outdated
],
check=True,
capture_output=True,
Expand Down
15 changes: 15 additions & 0 deletions tests/tensorizer_loader/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# SPDX-License-Identifier: Apache-2.0
from typing import Callable

import pytest
import os

from vllm import LLM
from vllm.distributed import cleanup_dist_env_and_memory
from vllm.model_executor.model_loader.tensorizer import TensorizerConfig


@pytest.fixture(autouse=True)
def allow_insecure_serialization():
os.environ["VLLM_ALLOW_INSECURE_SERIALIZATION"] = "1"
Comment thread
sangstar marked this conversation as resolved.
Outdated
Comment thread
sangstar marked this conversation as resolved.
Outdated

@pytest.fixture(autouse=True)
def cleanup():
cleanup_dist_env_and_memory(shutdown_ray=True)
Expand All @@ -14,3 +22,10 @@ def cleanup():
def tensorizer_config():
config = TensorizerConfig(tensorizer_uri="vllm")
return config


def assert_from_collective_rpc(engine: LLM,
closure: Callable,
closure_kwargs: dict):
res = engine.collective_rpc(method=closure, kwargs=closure_kwargs)
return all(res)
Loading