⚙️ Your current environment
- llmcompressor 0.12.1.dev100+g170a2e19 (traceback below); the same 16.00 GiB OOM also killed earlier runs on released 0.12.0.1 (both
pipeline="basic" and CPU-offload variants)
- transformers 5.10.1, torch 2.11.0+cu130
- 1x RTX 5090 32 GB (sm_120), driver 580.173.02, Ubuntu 24.04
- Dataset:
HuggingFaceH4/ultrachat_200k train_sft, 128 samples, rendered through the model chat template. Longest sample 3,994 tokens; only 10 of 128 exceed 2,048.
🐛 Describe the bug
Calling oneshot() with a text dataset and no max_seq_length reliably OOMs a 32 GB card during calibration of Qwen3-8B, with the allocation landing in transformers' attention-mask expansion:
File ".../transformers/masking_utils.py", line 52, in and_mask
result = result & mask(batch_idx, head_idx, q_idx, kv_idx).to(result.device)
torch.OutOfMemoryError: CUDA out of memory. Tried to allocate 16.00 GiB.
Setting max_seq_length=2048 and changing nothing else makes the identical run complete with headroom. We have not pinned down which broadcast produces the 16.00 GiB request (calibration batch_size defaults to 1, so it is not simple cross-sample padding); full logs available on request.
What makes this worth an issue is how misleading the failure is. The error points at GPU capacity, not sample length, so the natural responses are pipeline="basic", CPU offload via device_map, or concluding the model does not fit the card. None of them help, and each failed attempt costs a full calibration cycle. It took us several such cycles to find the actual cause.
Related but distinct prior work: #2649 fixed truncation for pre-tokenized datasets, and #2917 fixed truncation state leaking into the saved tokenizer. This report is about the untruncated-text path and the quality of the failure when it bites.
Proposal, any of which would have saved the debugging time:
- Log a prominent warning when tokenizing calibration text with no
max_seq_length set, including the longest sample length found.
- Or apply a documented default truncation for text datasets (matching what most recipes in
examples/ opt into).
- Or catch OOM during calibration and re-raise with a hint naming
max_seq_length when long samples are present.
Happy to submit a small PR for option 1, or whichever direction maintainers prefer.
🛠️ Steps to reproduce
from datasets import load_dataset
from transformers import AutoTokenizer
from llmcompressor import oneshot
from llmcompressor.modifiers.quantization import QuantizationModifier
MODEL = "Qwen/Qwen3-8B"
tok = AutoTokenizer.from_pretrained(MODEL)
ds = load_dataset("HuggingFaceH4/ultrachat_200k", split="train_sft") \
.shuffle(seed=3407).select(range(128))
ds = ds.map(lambda ex: {"text": tok.apply_chat_template(ex["messages"], tokenize=False)},
remove_columns=ds.column_names)
recipe = QuantizationModifier(targets="Linear", scheme="NVFP4", ignore=["lm_head"])
oneshot(model=MODEL, dataset=ds, recipe=recipe,
num_calibration_samples=128, output_dir="out-nvfp4") # no max_seq_length -> OOM on 32 GB
Add max_seq_length=2048 to the oneshot() call and it completes.
Hit while producing the quantization benchmark at https://github.com/Rodder5/sm120-quant-bench.
⚙️ Your current environment
pipeline="basic"and CPU-offload variants)HuggingFaceH4/ultrachat_200ktrain_sft, 128 samples, rendered through the model chat template. Longest sample 3,994 tokens; only 10 of 128 exceed 2,048.🐛 Describe the bug
Calling
oneshot()with a text dataset and nomax_seq_lengthreliably OOMs a 32 GB card during calibration of Qwen3-8B, with the allocation landing in transformers' attention-mask expansion:Setting
max_seq_length=2048and changing nothing else makes the identical run complete with headroom. We have not pinned down which broadcast produces the 16.00 GiB request (calibrationbatch_sizedefaults to 1, so it is not simple cross-sample padding); full logs available on request.What makes this worth an issue is how misleading the failure is. The error points at GPU capacity, not sample length, so the natural responses are
pipeline="basic", CPU offload via device_map, or concluding the model does not fit the card. None of them help, and each failed attempt costs a full calibration cycle. It took us several such cycles to find the actual cause.Related but distinct prior work: #2649 fixed truncation for pre-tokenized datasets, and #2917 fixed truncation state leaking into the saved tokenizer. This report is about the untruncated-text path and the quality of the failure when it bites.
Proposal, any of which would have saved the debugging time:
max_seq_lengthset, including the longest sample length found.examples/opt into).max_seq_lengthwhen long samples are present.Happy to submit a small PR for option 1, or whichever direction maintainers prefer.
🛠️ Steps to reproduce
Add
max_seq_length=2048to theoneshot()call and it completes.Hit while producing the quantization benchmark at https://github.com/Rodder5/sm120-quant-bench.