Skip to content

[Quantization] enable multi-backend bitsandbytes - #10574

Closed
hlky wants to merge 4 commits into
huggingface:mainfrom
hlky:bnb-multi-backend
Closed

[Quantization] enable multi-backend bitsandbytes#10574
hlky wants to merge 4 commits into
huggingface:mainfrom
hlky:bnb-multi-backend

Conversation

@hlky

@hlkyhlky commented Jan 14, 2025

Copy link
Copy Markdown
Contributor

What does this PR do?

Mainly copied from transformers PR.

May need to look at

_, is_loaded_in_4bit_bnb, is_loaded_in_8bit_bnb=_check_bnb_status(module)
if (is_loaded_in_4bit_bnboris_loaded_in_8bit_bnb) anddtypeisnotNone:
logger.warning(
f"The module '{module.__class__.__name__}' has been loaded in `bitsandbytes` {'4bit'ifis_loaded_in_4bit_bnbelse'8bit'} and conversion to {dtype} is not supported. Module is still in {'4bit'ifis_loaded_in_4bit_bnbelse'8bit'} precision."
)
ifis_loaded_in_8bit_bnbanddeviceisnotNone:
logger.warning(
f"The module '{module.__class__.__name__}' has been loaded in `bitsandbytes` 8bit and moving it to {device} via `.to()` is not supported. Module is still on {module.device}."
)
# This can happen for `transformer` models. CPU placement was added in
# https://github.com/huggingface/transformers/pull/33122. So, we guard this accordingly.
ifis_loaded_in_4bit_bnbanddeviceisnotNoneandis_transformers_version(">", "4.44.0"):
module.to(device=device)
elifnotis_loaded_in_4bit_bnbandnotis_loaded_in_8bit_bnb:
module.to(device, dtype)

Test results are same as nightly https://github.com/huggingface/diffusers/actions/runs/12758480172/job/35560601164

RUN_SLOW=1 pytest -v -s tests/quantization/bnb/
===================================================================================== short test summary info =====================================================================================
FAILED tests/quantization/bnb/test_mixed_int8.py::SlowBnb8bitTests::test_generate_quality_dequantize - NotImplementedError: Only row-major format inputs are supported, but got format `col32`
FAILED tests/quantization/bnb/test_mixed_int8.py::SlowBnb8bitTests::test_quality - AssertionError: False is not true
===================================================================== 2 failed, 42 passed, 26 warnings in 1601.02s (0:26:41) ======================================================================

Fixes#10395

Who can review?

Anyone in the community is free to review the PR once the tests have passed. Feel free to tag
members/contributors who may be interested in your PR.

@sayakpaul

@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

Comment on lines +94 to +95
if set(device_map.values()) == {"cpu"} and bnb_multibackend_is_enabled:
pass

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because bnb is supported on intel CPUs?

if "cpu" in device_map_without_no_convert.values() or "disk" in device_map_without_no_convert.values():
if set(device_map.values()) == {"cpu"} and bnb_multibackend_is_enabled:
pass
elif "cpu" in device_map_without_no_convert.values() or "disk" in device_map_without_no_convert.values():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The common piece of code between the two utilities could be clubbed into a small function and reused?

Previously we didn't do because it was relatively small and was better off in-line.

if "cpu" in device_map_without_no_convert.values() or "disk" in device_map_without_no_convert.values():
if set(device_map.values()) == {"cpu"} and bnb_multibackend_is_enabled:
pass
elif "cpu" in device_map_without_no_convert.values() or "disk" in device_map_without_no_convert.values():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The common piece of code between the two utilities could be clubbed into a small function and reused?

Previously we didn't do because it was relatively small and was better off in-line.

state.CxB, state.SB = bnb.functional.transform(weight.data, to_order=state.formatB)
out32, Sout32 = bnb.functional.igemmlt(im, state.CxB, Sim, state.SB)
return bnb.functional.mm_dequant(out32, Sout32, SCim, state.SCB, bias=None).t()
return bnb.functional.mm_dequant(out32, Sout32, SCim, state.SCB, bias=None).t().to(dtype)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: #10401

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will rebase after that PR has merged.

return is_loaded_in_4bit_bnb or is_loaded_in_8bit_bnb, is_loaded_in_4bit_bnb, is_loaded_in_8bit_bnb


def _validate_bnb_multi_backend_availability(raise_exception):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matthewdouglas I wonder if it makes sense have these as utility functions in bitsandbytes so that they can be reused in transformers and diffusers (and any other libraries)?

return True


@lru_cache

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually don't do lru_cache in import_utils.py. Any specific reasons?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from transformers, not sure on the context.

@sayakpaulsayakpaul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments but this is already very good!

May need to look at

Anything specific? Not seeing anything CUDA-specific.

@sayakpaul

Copy link
Copy Markdown
Member

Test results are same as nightly

Were the tests run on the aws-g6e-xlarge-plus runner? If so, tests/quantization/bnb/test_mixed_int8.py::SlowBnb8bitTests::test_quality should have passed. Will take a look.

@github-actions

Copy link
Copy Markdown
Contributor

This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread.

Please note that issues that do not follow the contributing guidelines are likely to be ignored.

@github-actionsgithub-actionsBot added the stale Issues that haven't received updates label Feb 13, 2025
@vladmandic

Copy link
Copy Markdown
Contributor

ping to remove stale

@github-actionsgithub-actionsBot removed the stale Issues that haven't received updates label Feb 14, 2025
@github-actions

Copy link
Copy Markdown
Contributor

This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread.

Please note that issues that do not follow the contributing guidelines are likely to be ignored.

@github-actionsgithub-actionsBot added the stale Issues that haven't received updates label Mar 14, 2025
@hlkyhlky closed this Apr 15, 2025
@hlky
hlky deleted the bnb-multi-backend branch April 15, 2025 12:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

staleIssues that haven't received updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Quantization] enable multi-backend bitsandbytes

4 participants

@hlky@HuggingFaceDocBuilderDev@sayakpaul@vladmandic