Transformers documentation

Bitsandbytes

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Bitsandbytes

bitsandbytes ライブラリは、ハードウェアアクセラレータの関数に対する軽量な Python ラッパーを通じて、LLM 用の量子化ツールを提供します。メモリフットプリントを削減することで、限られた計算リソースを用いて大規模モデルを扱うことを可能にします。

bitsandbytes のコア機能として、以下を提供します:

  • 量子化されたLinearレイヤー: 標準的なPyTorchのlinearレイヤーを、メモリ効率に優れた量子化された代替レイヤーに置き換えるLinear8bitLtおよびLinear4bitレイヤー
  • 最適化されたオプティマイザー: optimモジュールを通じて、一般的なオプティマイザーの8ビット版を提供し、メモリ要件を削減しながら大規模モデルの学習を可能にします
  • 行列積: 量子化形式を活用した最適化された行列積演算

bitsandbytesには、主に2つの量子化機能があります。

  1. LLM.int8() - 推論をより利用しやすくする8ビット量子化手法であり、性能の大幅な低下を伴いません。単純な量子化とは異なり、LLM.int8()は重要な計算に対して動的に高い精度を維持し、モデルの感度の高い部分における情報損失を防ぎます。

  2. QLoRA - 学習可能な低ランク適応(LoRA)重みの小さなセットを挿入することで、学習可能性を維持しながらモデルをさらに圧縮する4ビット量子化技術。

注: ユーザーフレンドリーな量子化体験を得るには、bitsandbytes の コミュニティスペース を利用できます。

bitsandbytes をインストールするには、以下のコマンドを実行してください。

pip install --upgrade transformers accelerate bitsandbytes

ソースからコンパイルするには、bitsandbytes インストールガイドの手順に従ってください。

ハードウェアの互換性

bitsandbytes は、CUDA バージョン 11.8 - 13.0 対応の NVIDIA GPU、Intel XPU、Intel Gaudi (HPU)、および CPU でサポートされています。追加のプラットフォームへの対応に向けた取り組みが進行中です。フィードバックの提供やテストにご興味がある場合は、詳細については bitsandbytes リポジトリ をご確認ください。

NVIDIA GPU (CUDA)

このバックエンドは、Linux x86-64、Linux aarch64、および Windows プラットフォームでサポートされています。

機能最低限のハードウェア要件
8ビットオプティマイザーNVIDIA Pascal (GTX 10X0 シリーズ、P100) 以降の GPU *
LLM.int8()NVIDIA Turing(RTX 20X0 シリーズ、T4)以降の GPU
NF4/FP4量子化NVIDIA Pascal (GTX 10X0 シリーズ、P100) 以降の GPU *

Intel GPU(XPU)

このバックエンドは、Linux x86-64 および Windows x86-64 プラットフォームでサポートされています。

Intel Gaudi (HPU)

このバックエンドは、Gaudi2 および Gaudi3 において Linux x86-64 でサポートされています。

CPU

このバックエンドは、Linux x86-64、Linux aarch64、および Windows x86-64 プラットフォームでサポートされています。

量子化の例

BitsAndBytesConfig を from_pretrained() に渡すことでモデルを量子化できます。これは、Accelerate をサポートし、torch.nn.Linear レイヤーを含むモデルであれば、モダリティを問わず適用できます。

8ビット
4-bit
Quantizing a model in 8-bit halves the memory-usage, and for large models, set `device_map="auto"` to efficiently distribute the weights across all available GPUs.
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_8bit=True)

model_8bit = AutoModelForCausalLM.from_pretrained(
    "bigscience/bloom-1b7", 
    device_map="auto",
    quantization_config=quantization_config
)

デフォルトでは、torch.nn.LayerNorm などの他のすべてのモジュールは、デフォルトの torch dtype に設定されます。これらのモジュールのデータ型は、dtype パラメータで変更できます。dtype="auto" を設定すると、モデルの config.json ファイルで定義されたデータ型でモデルが読み込まれます。

import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_8bit=True)

model_8bit = AutoModelForCausalLM.from_pretrained(
    "facebook/opt-350m", 
    device_map="auto",
    quantization_config=quantization_config, 
    dtype="auto"
)
model_8bit.model.decoder.layers[-1].final_layer_norm.weight.dtype

モデルが8ビットに量子化されると、push_to_hub()を使用して量子化済みモデルをHubにプッシュできますが、そのためにはTransformersとbitsandbytesの最新バージョンを使用している必要があります。最新バージョンを使用している場合、まず量子化設定のconfig.jsonファイルがプッシュされ、その後、量子化済みモデルの重みがプッシュされます。

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_8bit=True)

model = AutoModelForCausalLM.from_pretrained(
    "bigscience/bloom-560m", 
    device_map="auto",
    quantization_config=quantization_config
)

model.push_to_hub("bloom-560m-8bit")

8ビットおよび4ビットの学習は、追加パラメータの学習のみサポートされています。

get_memory_footprint を使用して、メモリフットプリントを確認してください。

print(model.get_memory_footprint())

quantization_configなしで、from_pretrained()を使用して量子化モデルを読み込みます。

from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("{your_username}/bloom-560m-8bit", device_map="auto")

LLM.int8

このセクションでは、オフロード、外れ値のしきい値、モジュール変換のスキップ、ファインチューニングなど、8ビット量子化の特定の機能について詳しく見ていきます。

オフローディング

8-bitモデルでは、CPUとGPU間で重みをオフロードすることで、非常に大きなモデルをメモリに収めることができます。CPUにディスパッチされた重みはfloat32で保存され、8-bitに変換されることはありません。例えば、BitsAndBytesConfigを通じてbigscience/bloom-1b7のオフロードを有効にできます。

from transformers import AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(llm_int8_enable_fp32_cpu_offload=True)

lm_head 以外のすべてを GPU に収めるよう、カスタムのデバイスマップを設計し、lm_head は CPU にディスパッチします。

device_map = {
    "transformer.word_embeddings": 0,
    "transformer.word_embeddings_layernorm": 0,
    "lm_head": "cpu",
    "transformer.h": 0,
    "transformer.ln_f": 0,
}

次に、カスタムのdevice_mapとquantization_configを指定してモデルを読み込みます。

model_8bit = AutoModelForCausalLM.from_pretrained(
    "bigscience/bloom-1b7",
    dtype="auto",
    device_map=device_map,
    quantization_config=quantization_config,
)

外れ値の閾値

「アウトライア」とは、特定の閾値を超える隠れ状態の値を指し、これらの値は fp16 で計算されます。通常、これらの値は正規分布([-3.5, 3.5])に従いますが、大規模モデルでは分布が大幅に異なる場合があります([-60, 6] や [6, 60] など)。8-bit 量子化は値が約 5 程度の場合に良好に機能しますが、それを超えるとパフォーマンスに大きなペナルティが発生します。適切なデフォルトの閾値は 6 ですが、より不安定なモデル(小規模モデルやファインチューニング中)では、より低い閾値が必要になる場合があります。

モデルに最適な閾値を見つけるには、BitsAndBytesConfigのllm_int8_thresholdパラメータを調整してみてください。例えば、閾値を0.0に設定すると、精度がわずかに低下する可能性があるものの、推論が大幅に高速化されます。

from transformers import AutoModelForCausalLM, BitsAndBytesConfig

model_id = "bigscience/bloom-1b7"

quantization_config = BitsAndBytesConfig(
    llm_int8_threshold=0.0,
    llm_int8_enable_fp32_cpu_offload=True
)

model_8bit = AutoModelForCausalLM.from_pretrained(
    model_id,
    dtype="auto",
    device_map=device_map,
    quantization_config=quantization_config,
)

モジュール変換をスキップ

Jukebox などの一部のモデルでは、すべてのモジュールを 8 ビットに量子化すると不安定になる可能性があるため、量子化を省略する必要があります。Jukebox の場合、BitsAndBytesConfig の llm_int8_skip_modules パラメータを使用して、lm_head モジュールをスキップする必要があります。

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

model_id = "bigscience/bloom-1b7"

quantization_config = BitsAndBytesConfig(
    llm_int8_skip_modules=["lm_head"],
)

model_8bit = AutoModelForCausalLM.from_pretrained(
    model_id,
    dtype="auto",
    device_map="auto",
    quantization_config=quantization_config,
)

ファインチューニング

PEFT ライブラリは、flan-t5-large や facebook/opt-6.7b のような大規模モデルのファインチューニングを、8ビット量子化と組み合わせてサポートしています。モデルは自動的に GPU にロードされるため、トレーニング時に device_map パラメータを渡す必要はありません。ただし、device_map パラメータ(device_map="auto" は推論時のみ使用してください)でデバイスマップをカスタマイズすることも可能です。

QLoRA

このセクションでは、4ビット量子化の特定の機能、例えば計算データ型の変更、Normal Float 4 (NF4) データ型、およびネスト量子化について解説します。

計算データ型

BitsAndBytesConfig でデータ型を float32(デフォルト値)から bf16 に変更して、計算を高速化します。

import torch
from transformers import BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16)

通常の Float 4 (NF4)

NF4 は QLoRA の論文で提案された 4 ビットデータ型で、正規分布から初期化された重みに適応されています。4 ビットのベースモデルの学習には NF4 を使用してください。

from transformers import BitsAndBytesConfig

nf4_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
)

model_nf4 = AutoModelForCausalLM.from_pretrained(model_id, dtype="auto", quantization_config=nf4_config)

推論において、bnb_4bit_quant_typeはパフォーマンスに大きな影響を与えません。ただし、モデルの重みと整合性を保つため、bnb_4bit_compute_dtypeとdtypeの値を使用する必要があります。

ネストされた量子化

ネスト量子化により、追加の性能コストなしにさらなるメモリを節約できます。この機能は、すでに量子化された重みに対して2回目の量子化を実行し、パラメータあたり追加で0.4ビットを節約します。例えば、ネスト量子化を使用すると、シーケンス長1024、バッチサイズ1、4ステップの勾配蓄積を有効にした設定で、16GBのNVIDIA T4 GPU上でLlama-13bモデルのファインチューニングを行うことができます。

from transformers import BitsAndBytesConfig

double_quant_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_use_double_quant=True,
)

model_double_quant = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-13b-chat-hf", dtype="auto", quantization_config=double_quant_config)

bitsandbytesモデルのデクアンタイズ

量子化されたモデルは、dequantize() を使用して元の精度に復元できますが、これにより品質が低下する可能性があります。デクォンタイズされたモデルを収容するのに十分な GPU メモリがあることを確認してください。

from transformers import AutoModelForCausalLM, BitsAndBytesConfig, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m", BitsAndBytesConfig(load_in_4bit=True))
model.dequantize()

リソース

8-bit量子化の詳細については、Hugging Face Transformers、Accelerate、bitsandbytesを用いた大規模transformers向け8-bit行列積のやさしい入門を参照してください。

Try 4-bit quantization in this notebook and learn more about its details in Making LLMs even more accessible with bitsandbytes, 4-bit quantization and QLoRA.

Update on GitHub