accelerate 1.x moves a quantized model, which transformers 4.42 forbids

The last reason MM-Embed ran on the CPU, and the one that only the new
diagnosis could have found. Its quantized GPU load died in accelerate's own
frame:

    transformers/modeling_utils.py:3904 in from_pretrained
      dispatch_model(model, **device_map_kwargs)
    accelerate/big_modeling.py:514 in dispatch_model
      model.to(device)
    transformers/modeling_utils.py:2774 in to
      ValueError: `.to` is not supported for `4-bit` or `8-bit` bitsandbytes
      models.

accelerate 1.x takes a `model.to(device)` shortcut for a single-device map, and
transformers 4.42 refuses that for a bnb model -- so the fallback ran it on the
CPU at 30x the latency and 33 GB of host RAM, for a model that fits in 5.7 GB
of card. accelerate==0.32.1 now sits in that pin's extras with peft, datasets,
pyarrow and bitsandbytes; the shared requirements carry none of them, because
only the quantizing pin needs them.

Verified live on zeiss after the relaunch:

    [tf4-embed] nvidia/MM-Embed ready on cuda (4096-d, transformers 4.42.4,
                quantized)
    card: 5666 MiB   (the planner estimated 5.18 GB)
    text: dims=4096 finite=True   image: dims=4096 finite=True
Co-Authored-By: 's avatarClaude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T3rZozi1Ehk96NG1WesgC
parent a7ad01c1
......@@ -125,7 +125,25 @@ PIN_EXTRAS = {
# is the package that refuses numpy 1.x ("pyarrow requires NumPy 2.0 or
# newer, found 1.26.4"). Pinning datasets without it fixes the version that
# was named in the error and not the one that caused it.
"4.42.4": ("peft==0.11.1", "datasets==2.20.0", "pyarrow==16.1.0"),
"4.42.4": ("peft==0.11.1", "datasets==2.20.0", "pyarrow==16.1.0",
# accelerate too, and this one is not about numpy. Its 1.x
# `dispatch_model` takes a `model.to(device)` shortcut for a
# single-device map, which transformers 4.42 forbids for a
# bitsandbytes model -- so a quantized GPU load died in
# accelerate's own frame:
#
# transformers/modeling_utils.py:3904 in from_pretrained
# dispatch_model(model, **device_map_kwargs)
# accelerate/big_modeling.py:514 in dispatch_model
# model.to(device)
# transformers/modeling_utils.py:2774 in to
# ValueError: `.to` is not supported for `4-bit` or `8-bit`
# bitsandbytes models.
#
# and the model fell back to the CPU: 30x slower and 33 GB of
# host RAM for what fits in 5 GB of card.
"accelerate==0.32.1",
"bitsandbytes>=0.45"),
}
#: …and what each of those adds to the import probe, so a venv missing one is
......@@ -134,7 +152,7 @@ PIN_PROBE_IMPORTS = {
# pyarrow directly as well as through datasets: it is the one that refuses
# numpy 1.x, and probing it by name repairs a venv whose pyarrow drifted
# without relying on `import datasets` to notice.
"4.42.4": ("peft", "datasets", "pyarrow"),
"4.42.4": ("peft", "datasets", "pyarrow", "accelerate", "bitsandbytes"),
}
......@@ -193,8 +211,7 @@ def model_for(name) -> Optional[Tf4Model]:
#: timm/einops/PIL, returned early, and the model failed with "This modeling
#: file requires the following packages that were not found in your
#: environment: peft".
_PROBE_IMPORTS = ("torch", "transformers", "timm", "einops", "PIL",
"bitsandbytes", "accelerate")
_PROBE_IMPORTS = ("torch", "transformers", "timm", "einops", "PIL")
#: The same pins as requirements-embedders-tf4.txt, for installs that cannot see
#: it. The container bind-mounts codai/, tools/ and third_party/ over the image,
......@@ -214,8 +231,6 @@ _FALLBACK_PINS = (
"numpy>=1.26",
"sentencepiece>=0.2",
"protobuf>=4.25",
"bitsandbytes>=0.45",
"accelerate>=1.0",
# MM-Embed's chain (peft, datasets) is NOT here: those two are pinned per
# transformers generation, see PIN_EXTRAS.
)
......
......@@ -63,8 +63,12 @@ protobuf>=4.25
# (including which modules to leave at full precision: a VL embedder's vision
# tower and projector) is decided by the parent and handed over as JSON,
# because the child cannot import coderai to ask.
bitsandbytes>=0.45
accelerate>=1.0
# bitsandbytes and accelerate are NOT here either, for the same reason as peft
# and datasets: only the quantizing pin needs them, and accelerate in
# particular has to match the transformers generation. accelerate 1.x's
# dispatch_model calls `model.to(device)` for a single-device map, which
# transformers 4.42 forbids for a bitsandbytes model -- so the quantized GPU
# load died in accelerate's frame and the model ran on the CPU instead.
# MM-Embed's dependency chain, which its repo declares nowhere a resolver can
# see and which transformers checks by SCANNING the modeling file's imports:
......
......@@ -484,16 +484,14 @@ def test_the_probe_covers_every_requirement_the_models_need(w):
pins = {p.split(">")[0].split("=")[0].strip().lower()
for p in w._FALLBACK_PINS}
# torch/transformers are probed under their import names already.
for pkg, module in (("bitsandbytes", "bitsandbytes"),
("accelerate", "accelerate"),
("timm", "timm"),
("einops", "einops")):
for pkg, module in (("timm", "timm"), ("einops", "einops")):
assert pkg in pins, pkg
assert module in w._PROBE_IMPORTS, module
# …and the per-generation extras likewise, against their own pin's probe.
for pin, extras in w.PIN_EXTRAS.items():
for spec in extras:
name = spec.split("=")[0]
# A spec is either `pkg==x.y` or `pkg>=x.y`.
name = spec.split("=")[0].rstrip("><!~")
assert name in w.probe_imports(pin), (pin, name)
assert name not in w._PROBE_IMPORTS, \
f"{name} is pinned per generation; probing it for every pin would " \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment