Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-compressed-tensors for
openSUSE:Factory checked in at 2026-07-18 22:25:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-compressed-tensors (Old)
and /work/SRC/openSUSE:Factory/.python-compressed-tensors.new.24530 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-compressed-tensors"
Sat Jul 18 22:25:17 2026 rev:2 rq:1366537 version:0.17.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-compressed-tensors/python-compressed-tensors.changes
2026-07-15 16:54:15.924208851 +0200
+++
/work/SRC/openSUSE:Factory/.python-compressed-tensors.new.24530/python-compressed-tensors.changes
2026-07-18 22:26:30.757159978 +0200
@@ -1,0 +2,8 @@
+Sat Jul 18 18:33:14 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to version 0.17.1:
+ * Support loading safetensors on the meta device
+ * Use explicit class patching for load_offloaded_model
+ * Ignore non-linear MoE gate layers
+
+-------------------------------------------------------------------
Old:
----
compressed_tensors-0.17.0.tar.gz
New:
----
compressed_tensors-0.17.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-compressed-tensors.spec ++++++
--- /var/tmp/diff_new_pack.ZE5dHz/_old 2026-07-18 22:26:31.509185221 +0200
+++ /var/tmp/diff_new_pack.ZE5dHz/_new 2026-07-18 22:26:31.509185221 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-compressed-tensors
-Version: 0.17.0
+Version: 0.17.1
Release: 0
Summary: Library for utilization of compressed safetensors of neural
network models
License: Apache-2.0
++++++ compressed_tensors-0.17.0.tar.gz -> compressed_tensors-0.17.1.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/compressed_tensors-0.17.0/.buildkite/pipeline.yml
new/compressed_tensors-0.17.1/.buildkite/pipeline.yml
--- old/compressed_tensors-0.17.0/.buildkite/pipeline.yml 1970-01-01
01:00:00.000000000 +0100
+++ new/compressed_tensors-0.17.1/.buildkite/pipeline.yml 2026-06-11
19:54:45.000000000 +0200
@@ -0,0 +1,6 @@
+steps:
+ # Test check pipeline
+ - label: "Compressed-Tensors Smoke, Sanity and Regression"
+ command: |
+ PIPELINE_FILE="$${TEST_RUNNER:-H100duo}"
+ buildkite-agent pipeline upload
.buildkite/test-check/test-check-$${PIPELINE_FILE}.yml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/.buildkite/test-check/scripts/test-check.sh
new/compressed_tensors-0.17.1/.buildkite/test-check/scripts/test-check.sh
--- old/compressed_tensors-0.17.0/.buildkite/test-check/scripts/test-check.sh
1970-01-01 01:00:00.000000000 +0100
+++ new/compressed_tensors-0.17.1/.buildkite/test-check/scripts/test-check.sh
2026-06-11 19:54:45.000000000 +0200
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# print OS info for debugging
+cat /etc/issue
+
+# fetch full history and tags (setuptools_scm derives version from git tags)
+git fetch --tags --unshallow 2>/dev/null || git fetch --tags
+
+# install system dependencies and uv
+apt-get update && apt-get install -y curl g++ gcc make
+curl -LsSf https://astral.sh/uv/install.sh | env UV_VERSION=0.11.18 sh
+
+# set up GPU and path
+export LD_LIBRARY_PATH=/usr/local/nvidia/lib64
+export PATH="$HOME/.local/bin:/usr/local/nvidia/bin:$PATH"
+nvidia-smi
+
+# create venv and install dependencies
+uv venv testvenv --python 3.12
+source testvenv/bin/activate
+
+export UV_TORCH_BACKEND=cu130
+export HF_HOME=/model-cache
+uv pip install .[dev] --index-strategy unsafe-best-match --extra-index-url
https://download.pytorch.org/whl/cu130
+
+# run tests
+make test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/.buildkite/test-check/test-check-H100duo.yml
new/compressed_tensors-0.17.1/.buildkite/test-check/test-check-H100duo.yml
--- old/compressed_tensors-0.17.0/.buildkite/test-check/test-check-H100duo.yml
1970-01-01 01:00:00.000000000 +0100
+++ new/compressed_tensors-0.17.1/.buildkite/test-check/test-check-H100duo.yml
2026-06-11 19:54:45.000000000 +0200
@@ -0,0 +1,49 @@
+steps:
+ - label: "Compressed-Tensors Smoke, Sanity and Regression - H100 duo"
+ agents:
+ queue: RedHat-H100-WDC
+
+ plugins:
+ - kubernetes:
+ podSpec:
+ serviceAccountName: buildkite-anyuid
+ securityContext:
+ fsGroup: 0
+ runAsUser: 0
+ runAsGroup: 0
+ nodeSelector:
+ vllm.ci/gpu-pool: upstream-ci-h100
+
+ containers:
+ - name: tests
+ image: buildkite/agent:3-ubuntu
+ command:
+ - chmod +x .buildkite/test-check/scripts/test-check.sh
+ - .buildkite/test-check/scripts/test-check.sh
+
+ resources:
+ limits:
+ nvidia.com/gpu: 2
+
+ volumeMounts:
+ - name: ci-cache
+ mountPath: /model-cache
+ readOnly: false
+ - name: devshm
+ mountPath: /dev/shm
+
+ env:
+ - name: HF_TOKEN
+ valueFrom:
+ secretKeyRef:
+ name: hf-token-secret
+ key: token
+
+ volumes:
+ - name: ci-cache
+ hostPath:
+ path: /var/mnt/ci-cache
+ type: DirectoryOrCreate
+ - name: devshm
+ emptyDir:
+ medium: Memory
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/.buildkite/test-check/test-check-L4solo.yml
new/compressed_tensors-0.17.1/.buildkite/test-check/test-check-L4solo.yml
--- old/compressed_tensors-0.17.0/.buildkite/test-check/test-check-L4solo.yml
1970-01-01 01:00:00.000000000 +0100
+++ new/compressed_tensors-0.17.1/.buildkite/test-check/test-check-L4solo.yml
2026-06-11 19:54:45.000000000 +0200
@@ -0,0 +1,36 @@
+steps:
+ - label: "Compressed-Tensors Smoke, Sanity and Regression - L4 solo"
+ agents:
+ queue: RedHat-L4-GCP
+
+ plugins:
+ - kubernetes:
+ podSpec:
+ nodeSelector:
+ pool: L4solo
+
+ containers:
+ - name: tests
+ image: buildkite/agent:3-ubuntu
+ command:
+ - chmod +x .buildkite/test-check/scripts/test-check.sh
+ - .buildkite/test-check/scripts/test-check.sh
+
+ resources:
+ limits:
+ nvidia.com/gpu: 1
+
+ volumeMounts:
+ - name: model-cache
+ mountPath: /model-cache
+ readOnly: false
+ - name: dshm
+ mountPath: /dev/shm
+
+ volumes:
+ - name: model-cache
+ persistentVolumeClaim:
+ claimName: buildkite-podpvc-ssd-blue
+ - name: dshm
+ emptyDir:
+ medium: Memory
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/.github/workflows/test-check.yaml
new/compressed_tensors-0.17.1/.github/workflows/test-check.yaml
--- old/compressed_tensors-0.17.0/.github/workflows/test-check.yaml
2026-06-03 18:32:50.000000000 +0200
+++ new/compressed_tensors-0.17.1/.github/workflows/test-check.yaml
1970-01-01 01:00:00.000000000 +0100
@@ -1,50 +0,0 @@
-name: Run Tests
-
-on:
- push:
- branches:
- - main
- - 'release/*'
- pull_request:
- branches:
- - main
- - 'release/*'
-
-jobs:
- python-tests:
- runs-on: ibm-wdc-k8s-vllm-h100-duo
- env:
- HF_TOKEN: ${{ secrets.HF_RED_HAT_READ_ONLY }}
- steps:
- - uses: actions/setup-python@v5
- with:
- python-version: '3.10'
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0
- fetch-tags: true
- - name: Install system dependencies
- run: |-
- sudo apt-get update
- sudo apt-get install -y --no-install-recommends g++ gcc make
- - name: Set Env
- run: pip3 install --upgrade pip setuptools
- - name: "⚙️ Install dependencies"
- run: pip3 install .[dev] --extra-index-url
https://download.pytorch.org/whl/cu129
- - name: clean up
- run: |
- echo "cleaning up disk space as GHA runner has limited disk size."
- python3 -m pip cache purge
- sudo rm -rf /usr/local/.ghcup
- sudo rm -rf /opt/hostedtoolcache/CodeQL
- sudo rm -rf /usr/local/lib/android/sdk/ndk
- sudo rm -rf /usr/share/dotnet
- sudo rm -rf /opt/ghc
- sudo rm -rf /usr/local/share/boost
- if [[ "$(cat /etc/issue)" =~ Ubuntu ]]; then
- sudo apt-get clean
- fi
- df -h
- shell: bash
- - name: "🔬 Running tests"
- run: make test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/compressed_tensors-0.17.0/PKG-INFO
new/compressed_tensors-0.17.1/PKG-INFO
--- old/compressed_tensors-0.17.0/PKG-INFO 2026-06-03 18:32:58.746444200
+0200
+++ new/compressed_tensors-0.17.1/PKG-INFO 2026-06-11 19:54:54.673481500
+0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: compressed-tensors
-Version: 0.17.0
+Version: 0.17.1
Summary: Library for utilization of compressed safetensors of neural network
models
Home-page: https://github.com/vllm-project/compressed-tensors
Author: The vLLM Project
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/src/compressed_tensors/offload/load.py
new/compressed_tensors-0.17.1/src/compressed_tensors/offload/load.py
--- old/compressed_tensors-0.17.0/src/compressed_tensors/offload/load.py
2026-06-03 18:32:50.000000000 +0200
+++ new/compressed_tensors-0.17.1/src/compressed_tensors/offload/load.py
2026-06-11 19:54:45.000000000 +0200
@@ -2,30 +2,25 @@
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
import contextlib
-import inspect
import os
import shutil
from functools import wraps
-from types import FrameType
import psutil
import torch
from compressed_tensors.distributed import is_distributed, is_source_process
from compressed_tensors.offload.convert import from_accelerate
+from compressed_tensors.utils import patch_attr
from loguru import logger
-from transformers import PreTrainedModel
-from transformers.models.auto.modeling_auto import _BaseAutoModelClass
+from transformers import AutoModelForCausalLM, PreTrainedModel
__all__ = ["load_offloaded_model"]
-cls_to_patch = _BaseAutoModelClass | PreTrainedModel
-
-
@contextlib.contextmanager
def load_offloaded_model(
- model_class: type[cls_to_patch] | None = None, extra_cpu_mem: int = 5e9
+ model_class: type[PreTrainedModel] = AutoModelForCausalLM, extra_cpu_mem:
int = 5e9
):
"""
Context manager used to load a transformers model with offloading
implemented by
@@ -40,31 +35,19 @@
`device_map="auto_offload"`, which means that the model will load as many
parameters
can fit onto the cpu, and any extra parameters will be loaded on disk.
- :param model_class: explicit class to patch. If None, patches all classes
in the
- caller's frame that are subclasses of _BaseAutoModelClass or
PreTrainedModel.
+ :param model_class: model class to patch
:param extra_cpu_mem: extra cpu memory to reserve for any operations not
related to
model loading (bytes). Defaults to 5Gb.
"""
- with contextlib.ExitStack() as stack:
- if model_class is not None:
- # Explicit class provided, patch only that class
- stack.enter_context(patch_from_pretrained(model_class,
extra_cpu_mem))
- else:
- # No class provided, use frame-based patching
- frame = _get_caller_frame()
- for obj in frame.f_globals.values():
- if isinstance(obj, type) and issubclass(obj, cls_to_patch):
- stack.enter_context(patch_from_pretrained(obj,
extra_cpu_mem))
-
- yield
+ original_from_pretrained = model_class.from_pretrained
+ patched_fn_called = False
+ @classmethod
+ @wraps(original_from_pretrained)
+ def patched(cls, *args, **kwargs):
+ nonlocal patched_fn_called
+ patched_fn_called = True
[email protected]
-def patch_from_pretrained(obj: cls_to_patch, extra_cpu_mem: int):
- original_func = obj.from_pretrained.__func__
-
- @wraps(original_func)
- def from_pretrained(cls, *args, **kwargs):
kwargs.setdefault("device_map", None)
# Rank 0 does loading, other ranks init on meta device
@@ -86,16 +69,22 @@
elif "max_memory" not in kwargs:
kwargs["max_memory"] = _get_device_memory() |
_get_cpu_memory(extra_cpu_mem)
- model = original_func(cls, *args, **kwargs)
+ model = original_from_pretrained(*args, **kwargs)
from_accelerate(model) # rank 0 shares weights with ranks via
offload/broadcast
return model
- try:
- obj.from_pretrained = from_pretrained.__get__(obj)
- yield
- finally:
- obj.from_pretrained = original_func.__get__(obj)
+ with patch_attr(model_class, "from_pretrained", patched):
+ try:
+ yield
+ finally:
+ if not patched_fn_called:
+ logger.warning(
+ f"`{model_class.__name__}.from_pretrained` was never
called. If "
+ "you are loading with a model class other than "
+ f"{model_class.__name__}, please pass as argument to "
+ "`load_offloaded_model`"
+ )
def _get_device_memory() -> dict[int, int]:
@@ -127,15 +116,3 @@
"Could not find shared memory at `/dev/shm`. Please add platform
suppport"
)
return psutil.virtual_memory().available
-
-
-def _get_caller_frame() -> FrameType:
- frame = inspect.currentframe()
- frame = frame.f_back.f_back # skip this function's caller's frame
- while frame is not None and "contextlib" in frame.f_code.co_filename:
- frame = frame.f_back # skip contextlib frames
-
- if frame is None:
- raise RuntimeError("Could not find caller frame")
-
- return frame
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/src/compressed_tensors/quantization/quant_config.py
new/compressed_tensors-0.17.1/src/compressed_tensors/quantization/quant_config.py
---
old/compressed_tensors-0.17.0/src/compressed_tensors/quantization/quant_config.py
2026-06-03 18:32:50.000000000 +0200
+++
new/compressed_tensors-0.17.1/src/compressed_tensors/quantization/quant_config.py
2026-06-11 19:54:45.000000000 +0200
@@ -5,13 +5,14 @@
from enum import Enum
from typing import Annotated, Any
+import torch
from compressed_tensors.config import CompressionFormat
from compressed_tensors.quantization.quant_args import DynamicType,
QuantizationArgs
from compressed_tensors.quantization.quant_scheme import (
QuantizationScheme,
preset_name_to_scheme,
)
-from compressed_tensors.quantization.utils import is_module_quantized,
module_type
+from compressed_tensors.quantization.utils import is_module_quantized
from pydantic import BaseModel, ConfigDict, Field
from torch.nn import Module
@@ -189,7 +190,7 @@
kv_cache_scheme: QuantizationArgs | None = None
for name, submodule in model.named_modules():
- layer_type: str = module_type(submodule)
+ layer_type: str = get_vllm_module_type(submodule)
# add config group if quantized non-attention or attention quant
has_config_group = is_module_quantized(submodule) and (
@@ -275,3 +276,18 @@
# TODO set `extra="forbid"` when upstream transformers is compatible
model_config = ConfigDict(extra="ignore")
+
+
+def get_vllm_module_type(module: torch.nn.Module) -> str:
+ """
+ Returns a string representing the module type used when loading in vLLM.
+ This is typically going to be the same as the `torch.nn.Module` type,
+ however specific cases like MoE gate layers need to be treated like
"Linear"
+ layers for the purposes of config matching.
+ """
+
+ module_type = type(module).__name__
+ if "Router" in module_type or "Gate" in module_type or "Gating" in
module_type:
+ module_type = "Linear"
+
+ return module_type
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/src/compressed_tensors/utils/safetensors_load.py
new/compressed_tensors-0.17.1/src/compressed_tensors/utils/safetensors_load.py
---
old/compressed_tensors-0.17.0/src/compressed_tensors/utils/safetensors_load.py
2026-06-03 18:32:50.000000000 +0200
+++
new/compressed_tensors-0.17.1/src/compressed_tensors/utils/safetensors_load.py
2026-06-11 19:54:45.000000000 +0200
@@ -39,6 +39,24 @@
WeightMappingType = dict[str, str]
NestedWeightMappingType = dict[str, WeightMappingType]
+str_to_torch_dtype = {
+ "BOOL": torch.bool,
+ "U8": torch.uint8,
+ "I8": torch.int8,
+ "I16": torch.int16,
+ "U16": torch.uint16,
+ "F16": torch.float16,
+ "BF16": torch.bfloat16,
+ "I32": torch.int32,
+ "U32": torch.uint32,
+ "F32": torch.float32,
+ "F64": torch.float64,
+ "I64": torch.int64,
+ "U64": torch.uint64,
+ "F8_E4M3": torch.float8_e4m3fn,
+ "F8_E5M2": torch.float8_e5m2,
+}
+
def is_weights_file(file_name: str) -> bool:
"""
@@ -478,8 +496,8 @@
"""
tensors: dict[str, torch.Tensor] = {}
for source_file, tensor_names in inverse_weight_map.items():
- with safe_open(source_file, framework="pt", device=str(device)) as f:
- keys = f.keys()
+ with safe_open(source_file, framework="pt") as file:
+ keys = file.keys()
# if tensor_names is empty, pull all tensors
if tensor_names is None or len(tensor_names) == 0:
tensor_names = keys
@@ -489,7 +507,17 @@
f"Expected to find tensor {tensor_name} in "
f"{source_file}, but tensor was not found."
)
- tensors[tensor_name] = f.get_tensor(tensor_name)
+ if str(device) == "meta":
+ _slice = file.get_slice(tensor_name)
+ dtype = str_to_torch_dtype[_slice.get_dtype()]
+ size = _slice.get_shape()
+ tensors[tensor_name] = torch.empty(
+ size=size, dtype=dtype, device="meta"
+ )
+ else:
+ tensors[tensor_name] = file.get_tensor(tensor_name).to(
+ device=device
+ )
return tensors
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/src/compressed_tensors/version.py
new/compressed_tensors-0.17.1/src/compressed_tensors/version.py
--- old/compressed_tensors-0.17.0/src/compressed_tensors/version.py
2026-06-03 18:32:58.000000000 +0200
+++ new/compressed_tensors-0.17.1/src/compressed_tensors/version.py
2026-06-11 19:54:54.000000000 +0200
@@ -17,5 +17,5 @@
__version_tuple__: VERSION_TUPLE
version_tuple: VERSION_TUPLE
-__version__ = version = '0.17.0'
-__version_tuple__ = version_tuple = (0, 17, 0)
+__version__ = version = '0.17.1'
+__version_tuple__ = version_tuple = (0, 17, 1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/src/compressed_tensors.egg-info/PKG-INFO
new/compressed_tensors-0.17.1/src/compressed_tensors.egg-info/PKG-INFO
--- old/compressed_tensors-0.17.0/src/compressed_tensors.egg-info/PKG-INFO
2026-06-03 18:32:58.000000000 +0200
+++ new/compressed_tensors-0.17.1/src/compressed_tensors.egg-info/PKG-INFO
2026-06-11 19:54:54.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: compressed-tensors
-Version: 0.17.0
+Version: 0.17.1
Summary: Library for utilization of compressed safetensors of neural network
models
Home-page: https://github.com/vllm-project/compressed-tensors
Author: The vLLM Project
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/src/compressed_tensors.egg-info/SOURCES.txt
new/compressed_tensors-0.17.1/src/compressed_tensors.egg-info/SOURCES.txt
--- old/compressed_tensors-0.17.0/src/compressed_tensors.egg-info/SOURCES.txt
2026-06-03 18:32:58.000000000 +0200
+++ new/compressed_tensors-0.17.1/src/compressed_tensors.egg-info/SOURCES.txt
2026-06-11 19:54:54.000000000 +0200
@@ -7,6 +7,10 @@
pytest-xpu.ini
setup.cfg
setup.py
+.buildkite/pipeline.yml
+.buildkite/test-check/test-check-H100duo.yml
+.buildkite/test-check/test-check-L4solo.yml
+.buildkite/test-check/scripts/test-check.sh
.claude/skills/style.md
.claude/skills/test.md
.github/.gitkeep
@@ -15,7 +19,6 @@
.github/scripts/step-status
.github/workflows/quality-check.yaml
.github/workflows/stale.yml
-.github/workflows/test-check.yaml
examples/bit_packing/ex_quantize_and_pack.py
examples/bit_packing/int4_config.json
examples/convert_checkpoint/autoawq_example.py
@@ -170,6 +173,7 @@
tests/test_entrypoints/convert/converters/test_build_inverse_weight_maps.py
tests/test_entrypoints/convert/converters/test_ct_dequantizer.py
tests/test_entrypoints/convert/converters/test_fp8block_dequantizer.py
+tests/test_entrypoints/convert/converters/test_modelopt_nvfp4.py
tests/test_examples/test_bitmask_compression_ipynb.py
tests/test_modeling/test_attention_and_cache.py
tests/test_modeling/test_deepseekv3_kvcache_quant.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/tests/test_entrypoints/convert/converters/test_autoawq.py
new/compressed_tensors-0.17.1/tests/test_entrypoints/convert/converters/test_autoawq.py
---
old/compressed_tensors-0.17.0/tests/test_entrypoints/convert/converters/test_autoawq.py
2026-06-03 18:32:50.000000000 +0200
+++
new/compressed_tensors-0.17.1/tests/test_entrypoints/convert/converters/test_autoawq.py
2026-06-11 19:54:45.000000000 +0200
@@ -157,4 +157,6 @@
converter = AutoAWQConverter()
with pytest.raises(ValueError, match="without corresponding"):
- converter.validate({"model.layers.0.mlp.down_proj.qweight":
torch.zeros(1, 1)})
+ converter.validate(
+ {"model.layers.0.mlp.down_proj.qweight": torch.zeros(1, 1,
device="meta")}
+ )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/tests/test_entrypoints/convert/converters/test_ct_dequantizer.py
new/compressed_tensors-0.17.1/tests/test_entrypoints/convert/converters/test_ct_dequantizer.py
---
old/compressed_tensors-0.17.0/tests/test_entrypoints/convert/converters/test_ct_dequantizer.py
2026-06-03 18:32:50.000000000 +0200
+++
new/compressed_tensors-0.17.1/tests/test_entrypoints/convert/converters/test_ct_dequantizer.py
2026-06-11 19:54:45.000000000 +0200
@@ -39,34 +39,35 @@
return dequantizer
-def _create_dummy_tensors():
- return {
- "model.layers.0.mlp.up_proj.weight": torch.randint(
- -128, 127, (64, 64), dtype=torch.int8
- ),
- "model.layers.0.mlp.up_proj.weight_scale": torch.rand(
- 64, 1, dtype=torch.float32
- ),
- "model.layers.0.mlp.down_proj.weight": torch.randint(
- -128, 127, (64, 64), dtype=torch.int8
- ),
- "model.language_model.layers.0.input_layernorm.weight": torch.randn(
- 64, 1, dtype=torch.bfloat16
- ),
- "model.language_model.layers.0.pre_feedforward_layernorm.weight":
torch.randn(
- 64, 1, dtype=torch.bfloat16
- ),
- "model.language_model.layers.0.post_feedforward_layernorm.weight":
torch.randn(
- 64, 1, dtype=torch.bfloat16
- ),
- "model.layers.0.mlp.down_proj.weight_scale": torch.rand(
- 64, 1, dtype=torch.float32
- ),
- "model.layers.0.self_attn.q_proj.weight": torch.randn(
- 128, 64, dtype=torch.bfloat16
- ),
- "model.embed_tokens.weight": torch.randn(128, 64,
dtype=torch.bfloat16),
- }
+def _create_dummy_tensors(device: torch.device = torch.device("cpu")):
+ with device:
+ return {
+ "model.layers.0.mlp.up_proj.weight": torch.randint(
+ -128, 127, (64, 64), dtype=torch.int8
+ ),
+ "model.layers.0.mlp.up_proj.weight_scale": torch.rand(
+ 64, 1, dtype=torch.float32
+ ),
+ "model.layers.0.mlp.down_proj.weight": torch.randint(
+ -128, 127, (64, 64), dtype=torch.int8
+ ),
+ "model.language_model.layers.0.input_layernorm.weight":
torch.randn(
+ 64, 1, dtype=torch.bfloat16
+ ),
+ "model.language_model.layers.0.pre_feedforward_layernorm.weight":
torch.randn( # noqa: E501
+ 64, 1, dtype=torch.bfloat16
+ ),
+ "model.language_model.layers.0.post_feedforward_layernorm.weight":
torch.randn( # noqa: E501
+ 64, 1, dtype=torch.bfloat16
+ ),
+ "model.layers.0.mlp.down_proj.weight_scale": torch.rand(
+ 64, 1, dtype=torch.float32
+ ),
+ "model.layers.0.self_attn.q_proj.weight": torch.randn(
+ 128, 64, dtype=torch.bfloat16
+ ),
+ "model.embed_tokens.weight": torch.randn(128, 64,
dtype=torch.bfloat16),
+ }
@pytest.mark.unit
@@ -93,7 +94,7 @@
@pytest.mark.unit
def test_validate_passes_with_valid_tensors():
dequantizer = _create_dequantizer(ignore=["model.embed_tokens"])
- tensors = _create_dummy_tensors()
+ tensors = _create_dummy_tensors(device=torch.device("meta"))
dequantizer.validate(tensors)
@@ -101,7 +102,7 @@
@pytest.mark.unit
def test_validate_raises_on_missing_scale():
dequantizer = _create_dequantizer(ignore=["model.embed_tokens"])
- tensors = _create_dummy_tensors()
+ tensors = _create_dummy_tensors(device=torch.device("meta"))
del tensors["model.layers.0.mlp.up_proj.weight_scale"]
with pytest.raises(ValueError, match="Expected key"):
@@ -111,7 +112,7 @@
@pytest.mark.unit
def test_validate_raises_on_unconsumed_key():
dequantizer = _create_dequantizer(ignore=["model.embed_tokens"])
- tensors = _create_dummy_tensors()
+ tensors = _create_dummy_tensors(device=torch.device("meta"))
tensors["model.layers.0.mlp.up_proj.extra_param"] = torch.rand(64)
with pytest.raises(ValueError, match="unconsumed keys"):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/tests/test_entrypoints/convert/converters/test_fp8block_dequantizer.py
new/compressed_tensors-0.17.1/tests/test_entrypoints/convert/converters/test_fp8block_dequantizer.py
---
old/compressed_tensors-0.17.0/tests/test_entrypoints/convert/converters/test_fp8block_dequantizer.py
2026-06-03 18:32:50.000000000 +0200
+++
new/compressed_tensors-0.17.1/tests/test_entrypoints/convert/converters/test_fp8block_dequantizer.py
2026-06-11 19:54:45.000000000 +0200
@@ -133,6 +133,40 @@
), "Non-targeted tensor should not be modified"
[email protected]
+def test_fp8_block_converter_validate_with_meta_tensors():
+ """
+ Test that the converter's validate method works correctly with meta
tensors.
+ """
+ converter = FP8BlockDequantizer(
+ targets=[r"re:.*layer\d+\.mlp\..*proj$"], weight_block_size=(128, 128)
+ )
+
+ # Create mock tensors dict with FP8 weights and scale_inv tensors on meta
device
+ num_row_blocks = 2
+ num_col_blocks = 2
+
+ with torch.device("meta"):
+ tensors = {
+ "model.layer0.mlp.up_proj.weight": torch.empty(
+ 256, 256, dtype=torch.float8_e4m3fn
+ ),
+ "model.layer0.mlp.up_proj.weight_scale_inv": torch.empty(
+ num_row_blocks, num_col_blocks, dtype=torch.float32
+ ),
+ "model.layer1.mlp.down_proj.weight": torch.empty(
+ 256, 256, dtype=torch.float8_e4m3fn
+ ),
+ "model.layer1.mlp.down_proj.weight_scale_inv": torch.empty(
+ num_row_blocks, num_col_blocks, dtype=torch.float32
+ ),
+ "model.embed_tokens.weight": torch.empty(128, 128,
dtype=torch.bfloat16),
+ }
+
+ # Should not raise any errors
+ converter.validate(tensors)
+
+
def _verify_block_conversion(
result: torch.Tensor,
weight_fp8: torch.Tensor,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/tests/test_entrypoints/convert/converters/test_modelopt_nvfp4.py
new/compressed_tensors-0.17.1/tests/test_entrypoints/convert/converters/test_modelopt_nvfp4.py
---
old/compressed_tensors-0.17.0/tests/test_entrypoints/convert/converters/test_modelopt_nvfp4.py
1970-01-01 01:00:00.000000000 +0100
+++
new/compressed_tensors-0.17.1/tests/test_entrypoints/convert/converters/test_modelopt_nvfp4.py
2026-06-11 19:54:45.000000000 +0200
@@ -0,0 +1,127 @@
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
+
+import pytest
+import torch
+from compressed_tensors.entrypoints.convert import ModelOptNvfp4Converter
+
+
[email protected]
+def test_modelopt_nvfp4_converter_process():
+ """
+ Test that the converter's process method correctly transforms ModelOpt
NVFP4
+ tensors to compressed-tensors NVFP4 format.
+ """
+ converter =
ModelOptNvfp4Converter(targets=[r"re:.*layer\d+\.mlp\..*proj$"])
+
+ # Create mock tensors dict with ModelOpt NVFP4 format
+ input_scale = torch.tensor([2.0], dtype=torch.float32)
+ weight = torch.randint(0, 255, (256, 256), dtype=torch.uint8)
+ weight_scale = torch.rand(256, 1,
dtype=torch.float32).to(torch.float8_e4m3fn)
+ weight_scale_2 = torch.tensor([4.0], dtype=torch.float32)
+ embed_weight = torch.randn(128, 128, dtype=torch.bfloat16)
+
+ tensors = {
+ "model.layer0.mlp.up_proj.input_scale": input_scale,
+ "model.layer0.mlp.up_proj.weight": weight,
+ "model.layer0.mlp.up_proj.weight_scale": weight_scale,
+ "model.layer0.mlp.up_proj.weight_scale_2": weight_scale_2,
+ "model.embed_tokens.weight": embed_weight,
+ }
+
+ # Process the tensors
+ result = converter.process(tensors)
+
+ # Verify transformations
+ # input_scale -> input_global_scale (inverted)
+ assert "model.layer0.mlp.up_proj.input_scale" not in result
+ assert "model.layer0.mlp.up_proj.input_global_scale" in result
+ assert torch.allclose(
+ result["model.layer0.mlp.up_proj.input_global_scale"],
+ 1 / input_scale,
+ )
+
+ # weight -> weight_packed (renamed)
+ assert "model.layer0.mlp.up_proj.weight" not in result
+ assert "model.layer0.mlp.up_proj.weight_packed" in result
+ assert torch.equal(result["model.layer0.mlp.up_proj.weight_packed"],
weight)
+
+ # weight_scale stays the same
+ assert "model.layer0.mlp.up_proj.weight_scale" in result
+ assert (
+ result["model.layer0.mlp.up_proj.weight_scale"].data_ptr()
+ == weight_scale.data_ptr()
+ )
+
+ # weight_scale_2 -> weight_global_scale (inverted)
+ assert "model.layer0.mlp.up_proj.weight_scale_2" not in result
+ assert "model.layer0.mlp.up_proj.weight_global_scale" in result
+ assert torch.allclose(
+ result["model.layer0.mlp.up_proj.weight_global_scale"],
+ 1 / weight_scale_2,
+ )
+
+ # Non-targeted tensor should not be modified
+ assert torch.equal(result["model.embed_tokens.weight"], embed_weight)
+
+
[email protected]
+def test_modelopt_nvfp4_converter_get_dependencies():
+ """
+ Test that get_dependencies returns the correct dependent tensors for
+ targeted weight tensors.
+ """
+ converter = ModelOptNvfp4Converter(targets=[r"re:.*down_proj$"])
+
+ # Targeted layer should have dependencies
+ deps = converter.get_dependencies("model.layer0.mlp.down_proj.weight")
+ assert deps == {
+ "model.layer0.mlp.down_proj.input_scale",
+ "model.layer0.mlp.down_proj.weight_scale",
+ "model.layer0.mlp.down_proj.weight_scale_2",
+ }
+
+ # Non-targeted layer should have no dependencies
+ deps = converter.get_dependencies("model.layer0.mlp.up_proj.weight")
+ assert deps == set()
+
+ # Non-weight tensor should have no dependencies
+ deps =
converter.get_dependencies("model.layer0.mlp.down_proj.weight_scale")
+ assert deps == set()
+
+
[email protected]
+def test_modelopt_nvfp4_converter_validate_with_meta_tensors():
+ """
+ Test that the converter's validate method works correctly with meta
tensors.
+ """
+ converter =
ModelOptNvfp4Converter(targets=[r"re:.*layer\d+\.mlp\..*proj$"])
+
+ # Create mock tensors dict with NVFP4 tensors on meta device
+ with torch.device("meta"):
+ tensors = {
+ "model.layer0.mlp.up_proj.input_scale": torch.empty(1,
dtype=torch.float32),
+ "model.layer0.mlp.up_proj.weight": torch.empty(256, 256,
dtype=torch.uint8),
+ "model.layer0.mlp.up_proj.weight_scale": torch.empty(
+ 256, 1, dtype=torch.float8_e4m3fn
+ ),
+ "model.layer0.mlp.up_proj.weight_scale_2": torch.empty(
+ 1, dtype=torch.float32
+ ),
+ "model.layer1.mlp.down_proj.input_scale": torch.empty(
+ 1, dtype=torch.float32
+ ),
+ "model.layer1.mlp.down_proj.weight": torch.empty(
+ 256, 256, dtype=torch.uint8
+ ),
+ "model.layer1.mlp.down_proj.weight_scale": torch.empty(
+ 256, 1, dtype=torch.float8_e4m3fn
+ ),
+ "model.layer1.mlp.down_proj.weight_scale_2": torch.empty(
+ 1, dtype=torch.float32
+ ),
+ "model.embed_tokens.weight": torch.empty(128, 128,
dtype=torch.bfloat16),
+ }
+
+ # Should not raise any errors
+ converter.validate(tensors)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/compressed_tensors-0.17.0/tests/test_offload/test_load.py
new/compressed_tensors-0.17.1/tests/test_offload/test_load.py
--- old/compressed_tensors-0.17.0/tests/test_offload/test_load.py
2026-06-03 18:32:50.000000000 +0200
+++ new/compressed_tensors-0.17.1/tests/test_offload/test_load.py
2026-06-11 19:54:45.000000000 +0200
@@ -12,7 +12,7 @@
)
from compressed_tensors.offload.convert import to_accelerate
from compressed_tensors.offload.convert.from_accelerate import
_infer_module_device
-from compressed_tensors.offload.load import load_offloaded_model,
patch_from_pretrained
+from compressed_tensors.offload.load import load_offloaded_model
from tests.test_offload.conftest import (
assert_device_equal,
skip_if_mps_device,
@@ -58,7 +58,7 @@
@requires_gpu
@pytest.mark.parametrize("device_map,max_memory,first,second", TEST_PARAMETERS)
def test_load(device_map, max_memory, first, second, tmp_path):
- with load_offloaded_model():
+ with load_offloaded_model(AutoModelForCausalLM):
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-0.6B",
device_map=device_map,
@@ -131,7 +131,7 @@
received["kwargs"] = kwargs
return MagicMock()
- with patch_from_pretrained(FakeModel, extra_cpu_mem=0):
+ with load_offloaded_model(FakeModel, extra_cpu_mem=0):
FakeModel.from_pretrained("org/model", device_map="cpu",
torch_dtype="auto")
assert received["cls"] is FakeModel