Skip to content

Handle non-contiguous inputs in LLM.int8() CUDA ops - #2131

Open
Mazukiri wants to merge 1 commit into
bitsandbytes-foundation:mainfrom
Mazukiri:fix-int8-non-contiguous
Open

Mazukiri wants to merge 1 commit into
bitsandbytes-foundation:mainfrom
Mazukiri:fix-int8-non-contiguous

Conversation

@Mazukiri

Copy link
Copy Markdown

Summary

Fixes #2130

Test plan

  • New tests in TestNonContiguousInputs (tests/test_ops.py):
    • test_int8_vectorwise_quant_non_contiguous (threshold 0.0 and 6.0, with an outlier column)
    • test_int8_linear_matmul_non_contiguous
    • test_int8_mm_dequant_non_contiguous
  • New test test_linear8bitlt_non_contiguous_input (tests/test_linear8bitlt.py), covering h[:, 0] and h[:, -1:, :] with threshold 0.0 and 6.0.
  • NVIDIA L4 (sm_89), CUDA 13.0, torch 2.14.1, built from main @ a616886 with -DCOMPUTE_CAPABILITY=89: the 6 new CUDA test cases fail without the change and pass with it. With the change, TestNonContiguousInputs plus the new Linear8bitLt test give 84 passed, 36 skipped.
  • Existing int8 tests on the same L4: tests/test_ops.py, tests/test_linear8bitlt.py, tests/test_functional.py and tests/test_autograd.py, selected with -k "int8 or Int8 or matmullt or linear8bit or NonContiguous or non_contiguous or LLMInt8 or linear_no_igemmlt". With the change: 1338 passed, 52 skipped, 2 xfailed. Without it: 1332 passed, and the only failures are the 6 new CUDA test cases.
  • CPU: the new tests pass with and without the change, because the CPU path is not affected.
  • ruff check and ruff format --check (ruff 0.14.x) are clean.
  • End to end on the same L4 with main @ a616886. Models were loaded with load_in_8bit=True and dtype=torch.float16, and a batch of 8 was compared with running the same inputs one at a time:
    • distilbert-base-uncased-finetuned-sst-2-english: before the change, every sentence in the batch is labelled positive (agreement 0.50); after it, the labels match (agreement 1.00).
    • cross-encoder/ms-marco-MiniLM-L6-v2: the top-3 goes from [4, 0, 3] back to [0, 2, 6].

🤖 Generated with Claude Code

The CUDA implementations of int8_vectorwise_quant, int8_linear_matmul and
int8_mm_dequant pass raw pointers to the kernels and cuBLASLt, which assume
dense row-major storage. A strided view such as hidden_states[:, 0] was read
as if it were dense, so every row except the first was silently wrong.
Convert the inputs to contiguous first, as bitsandbytes-foundation#1859 did for the blockwise and
4-bit ops, and add regression tests.

Fixes bitsandbytes-foundation#2130

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LLM.int8(): int8 CUDA ops ignore input strides, so Linear8bitLt silently returns wrong rows for non-contiguous inputs like hidden_states[:, 0]

1 participant