Transformers documentation
torchao
torchao
torchao هو مكتبة لتحسين معمارية PyTorch تدعم أنواع بيانات مخصصة عالية الأداء، والتكميم، والتخلخل. وهو قابل للتركيب مع ميزات PyTorch الأصلية مثل torch.compile للحصول على استدلال وتدريب أسرع.
انظر إلى الجدول أدناه لمزيد من ميزات torchao.
| ميزة | الوصف |
|---|---|
| التدريب الواعي بالكمّية (QAT) | تدريب نماذج مُكمّمة مع فقدان دقة ضئيل (انظر قراءة README الخاصة بـ QAT) |
| التدريب باستخدام Float8 | تدريب عالي الإنتاجية باستخدام صيغ float8 (انظر إلى وثائق torchtitan وAccelerate) |
| دعم Sparsity | التخلخل شبه المهيكَل (2:4) لاستدلال أسرع (انظر إلى منشور المدونة تسريع تدريب الشبكات العصبية باستخدام التخلخل شبه المهيكَل (2:4)) |
| تكميم المُحسِّن | تقليل ذاكرة حالة المُحسِّن باستخدام متغيرات Adam ذات 4 و8 بت |
| تكميم ذاكرة KV | يتيح الاستدلال بسياق طويل بذاكرة أقل (انظر تكميم ذاكرة KV) |
| دعم النوى المخصصة | استخدم عملياتك الخاصة المتوافقة مع torch.compile |
| FSDP2 | قابلة للتركيب مع FSDP2 للتدريب |
راجع README.md الخاص بـ torchao لمزيد من التفاصيل حول المكتبة.
يدعم torchao تقنيات التكميم أدناه.
- A16W8 التكميم الديناميكي Float8
- كمّية A16W8 Float8 للأوزان فقط
- A8W8 Int8 التكميم الديناميكي
- كمّية A16W8 Int8 للأوزان فقط
- كمّية الأوزان فقط A16W4 Int4
- كمّية A16W4 Int4 للأوزان فقط + تمييع 2:4
- الكمّية التلقائية
يدعم torchao أيضًا التكوين على مستوى الوحدة (module) من خلال تحديد قاموس (dictionary) يربط بين الاسم الكامل (fully qualified name) للوحدة وإعدادات التكميم (quantization config) المقابلة لها. وهذا يتيح تجاوز تكميم طبقات معينة واستخدام إعدادات تكميم مختلفة للوحدات المختلفة.
تحقق من الجدول أدناه لمعرفة ما إذا كان جهازك متوافقًا.
| مكوّن | التوافق |
|---|---|
| إصدارات CUDA | ✅ cu118، cu126، cu128 |
| إصدارات XPU | ✅ pytorch2.8 |
| وحدة المعالجة المركزية | ✅ تغيير device_map="cpu" (انظر إلى الأمثلة أدناه) |
قم بتثبيت torchao من PyPi أو فهرس PyTorch باستخدام الأوامر التالية.
# Updating 🤗 Transformers to the latest version, as the example script below uses the new auto compilation
# Stable release from Pypi which will default to CUDA 12.6
pip install --upgrade torchao transformersالإصدار المستقر من فهرس PyTorch
pip install torchao --index-url https://download.pytorch.org/whl/cu126 # options are cpu/cu118/cu126/cu128torchao >= 0.15.0 is required. The string-based API (e.g., TorchAoConfig("int4_weight_only")) has been removed — use AOBaseConfig objects instead (see examples below).
أمثلة على التكميم
توفر TorchAO مجموعة متنوعة من إعدادات التكميم. يمكن تخصيص كل إعداد بشكل إضافي باستخدام معاملات مثل group_size وscheme وlayout لتحسين الأداء لمعماريات الأجهزة والنماذج المحددة.
لقائمة كاملة بالإعدادات المتاحة، راجع توثيق واجهة برمجة التطبيقات للكمّية.
يمكنك اختيار أنواع التكميم والإعدادات يدويًا، أو اختيار أنواع التكميم تلقائيًا.
أنشئ كائن TorchAoConfig وحدد نوع التكميم وgroup_size للأوزان المراد تكميمها (في حالتي int8 weight only وint4 weight only). اضبط cache_implementation على "static" لتفعيل torch.compile تلقائياً على طريقة forward.
سنُظهر أمثلةً على طرق التكميم الموصى بها بناءً على الأجهزة، مثل معالج الرسوميات A100، ومعالج الرسوميات H100، ومعالج وحدة المعالجة المركزية CPU.
torchao automatically compiles the model during the first inference if we set
cache_implementation="static". The model is recompiled every time batch size ormax_new_tokensis modified. Passdisable_compile=Truein generate() to quantize without compilation.
وحدة معالجة رسومات H100
import torch
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
from torchao.quantization import Float8DynamicActivationFloat8WeightConfig, Float8WeightOnlyConfig
quant_config = Float8DynamicActivationFloat8WeightConfig()
# or float8 weight only quantization
# quant_config = Float8WeightOnlyConfig()
quantization_config = TorchAoConfig(quant_type=quant_config)
# Load and quantize the model
quantized_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B-Instruct",
dtype="auto",
device_map="auto",
quantization_config=quantization_config
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
input_text = "What are we having for dinner?"
input_ids = tokenizer(input_text, return_tensors="pt").to(quantized_model.device, quantized_model.dtype)
# auto-compile the quantized model with `cache_implementation="static"` to get speed up
output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static")
print(tokenizer.decode(output[0], skip_special_tokens=True))import torch
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
from torchao.quantization import GemliteUIntXWeightOnlyConfig
# We integrated with gemlite, which optimizes for batch size N on A100 and H100
quant_config = GemliteUIntXWeightOnlyConfig(group_size=128)
quantization_config = TorchAoConfig(quant_type=quant_config)
# Load and quantize the model
quantized_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B-Instruct",
dtype="auto",
device_map="auto",
quantization_config=quantization_config
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
input_text = "What are we having for dinner?"
input_ids = tokenizer(input_text, return_tensors="pt").to(quantized_model.device, quantized_model.dtype)
# auto-compile the quantized model with `cache_implementation="static"` to get speed up
output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static")
print(tokenizer.decode(output[0], skip_special_tokens=True))وحدة معالجة رسومات A100
import torch
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
from torchao.quantization import Int8DynamicActivationInt8WeightConfig, Int8WeightOnlyConfig
quant_config = Int8DynamicActivationInt8WeightConfig()
# or int8 weight only quantization
# quant_config = Int8WeightOnlyConfig()
quantization_config = TorchAoConfig(quant_type=quant_config)
# Load and quantize the model
quantized_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B-Instruct",
dtype="auto",
device_map="auto",
quantization_config=quantization_config
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
input_text = "What are we having for dinner?"
input_ids = tokenizer(input_text, return_tensors="pt").to(quantized_model.device, quantized_model.dtype)
# auto-compile the quantized model with `cache_implementation="static"` to get speed up
output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static")
print(tokenizer.decode(output[0], skip_special_tokens=True))import torch
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
from torchao.quantization import GemliteUIntXWeightOnlyConfig, Int4WeightOnlyConfig
# For batch size N, we recommend gemlite, which may require autotuning
# default is 4 bit, 8 bit is also supported by passing `bit_width=8`
quant_config = GemliteUIntXWeightOnlyConfig(group_size=128)
# For batch size 1, we also have custom tinygemm kernel that's only optimized for this
# We can set `use_hqq` to `True` for better accuracy
# quant_config = Int4WeightOnlyConfig(group_size=128, use_hqq=True)
quantization_config = TorchAoConfig(quant_type=quant_config)
# Load and quantize the model
quantized_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B-Instruct",
dtype="auto",
device_map="auto",
quantization_config=quantization_config
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
input_text = "What are we having for dinner?"
input_ids = tokenizer(input_text, return_tensors="pt").to(quantized_model.device, quantized_model.dtype)
# auto-compile the quantized model with `cache_implementation="static"` to get speed up
output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static")
print(tokenizer.decode(output[0], skip_special_tokens=True))Intel XPU
import torch
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
from torchao.quantization import Int8DynamicActivationInt8WeightConfig, Int8WeightOnlyConfig
quant_config = Int8DynamicActivationInt8WeightConfig()
# or int8 weight only quantization
# quant_config = Int8WeightOnlyConfig()
quantization_config = TorchAoConfig(quant_type=quant_config)
# Load and quantize the model
quantized_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B-Instruct",
dtype="auto",
device_map="auto",
quantization_config=quantization_config
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
input_text = "What are we having for dinner?"
input_ids = tokenizer(input_text, return_tensors="pt").to(quantized_model.device, quantized_model.dtype)
# auto-compile the quantized model with `cache_implementation="static"` to get speed up
output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static")
print(tokenizer.decode(output[0], skip_special_tokens=True))import torch
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
from torchao.quantization import Int4WeightOnlyConfig
quant_config = Int4WeightOnlyConfig(group_size=128, int4_packing_format="plain_int32")
quantization_config = TorchAoConfig(quant_type=quant_config)
# Load and quantize the model
quantized_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B-Instruct",
dtype="auto",
device_map="auto",
quantization_config=quantization_config
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
input_text = "What are we having for dinner?"
input_ids = tokenizer(input_text, return_tensors="pt").to(quantized_model.device).to(quantized_model.dtype)
# auto-compile the quantized model with `cache_implementation="static"` to get speed up
output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static")
print(tokenizer.decode(output[0], skip_special_tokens=True))وحدة المعالجة المركزية
import torch
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
from torchao.quantization import Int8DynamicActivationInt8WeightConfig, Int8WeightOnlyConfig
quant_config = Int8DynamicActivationInt8WeightConfig()
# quant_config = Int8WeightOnlyConfig()
quantization_config = TorchAoConfig(quant_type=quant_config)
# Load and quantize the model
quantized_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B-Instruct",
dtype="auto",
device_map="cpu",
quantization_config=quantization_config
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
input_text = "What are we having for dinner?"
input_ids = tokenizer(input_text, return_tensors="pt").to(quantized_model.device, quantized_model.dtype)
# auto-compile the quantized model with `cache_implementation="static"` to get speed up
output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static")
print(tokenizer.decode(output[0], skip_special_tokens=True))يتطلب تكميم الأوزان فقط بدقة int4 على وحدة المعالجة المركزية (CPU) إصدار torchao 0.15.0 أو أحدث.
import torch
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
from torchao.prototype.quantization.int4 import PrototypeInt4WeightOnlyConfig
quantization_config = TorchAoConfig(PrototypeInt4WeightOnlyConfig(group_size=128, int4_choose_qparams_algorithm="tinygemm"))
# Load and quantize the model
quantized_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B-Instruct",
dtype="auto",
device_map="cpu",
quantization_config=quantization_config
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
input_text = "What are we having for dinner?"
input_ids = tokenizer(input_text, return_tensors="pt").to(quantized_model.device).to(quantized_model.dtype)
# auto-compile the quantized model with `cache_implementation="static"` to get speed up
output = quantized_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static")
print(tokenizer.decode(output[0], skip_special_tokens=True))التكميم لكل وحدة
1. تجاوز التكميم لطبقات معينة
باستخدام FqnToConfig يمكننا تحديد تكوين افتراضي لجميع الطبقات مع تجاوز التكميم لطبقات معينة.
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TorchAoConfig
model_id = "meta-llama/Llama-3.1-8B-Instruct"
from torchao.quantization import Int4WeightOnlyConfig, FqnToConfig
config = Int4WeightOnlyConfig(group_size=128)
# set default to int4 (for linears), and skip quantizing `model.layers.0.self_attn.q_proj`
quant_config = FqnToConfig({"_default": config, "model.layers.0.self_attn.q_proj": None})
quantization_config = TorchAoConfig(quant_type=quant_config)
quantized_model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto", dtype=torch.bfloat16, quantization_config=quantization_config)
# lm_head is not quantized and model.layers.0.self_attn.q_proj is not quantized
print("quantized model:", quantized_model)
tokenizer = AutoTokenizer.from_pretrained(model_id)
# Manual Testing
prompt = "Hey, are you conscious? Can you talk to me?"
inputs = tokenizer(prompt, return_tensors="pt").to(quantized_model.device, quantized_model.dtype)
generated_ids = quantized_model.generate(**inputs, max_new_tokens=128)
output_text = tokenizer.batch_decode(
generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False
)
print(output_text)2. تكميم طبقات مختلفة باستخدام إعدادات تكميم مختلفة (بدون تعبيرات نمطية)
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TorchAoConfig
model_id = "facebook/opt-125m"
from torchao.quantization import Int4WeightOnlyConfig, FqnToConfig, Int8DynamicActivationInt4WeightConfig, IntxWeightOnlyConfig, PerAxis, MappingType
weight_dtype = torch.int8
granularity = PerAxis(0)
mapping_type = MappingType.ASYMMETRIC
embedding_config = IntxWeightOnlyConfig(
weight_dtype=weight_dtype,
granularity=granularity,
mapping_type=mapping_type,
)
linear_config = Int8DynamicActivationInt4WeightConfig(group_size=128)
quant_config = FqnToConfig({"_default": linear_config, "model.decoder.embed_tokens": embedding_config, "model.decoder.embed_positions": None})
# set `include_embedding` to True in order to include embedding in quantization
# when `include_embedding` is True, we'll remove input embedding from `modules_not_to_convert` as well
quantization_config = TorchAoConfig(quant_type=quant_config, include_embedding=True)
quantized_model = AutoModelForCausalLM.from_pretrained(model_id, device_map="cpu", dtype=torch.bfloat16, quantization_config=quantization_config)
print("quantized model:", quantized_model)
# make sure embedding is quantized
print("embed_tokens weight:", quantized_model.model.decoder.embed_tokens.weight)
tokenizer = AutoTokenizer.from_pretrained(model_id)
# Manual Testing
prompt = "Hey, are you conscious? Can you talk to me?"
inputs = tokenizer(prompt, return_tensors="pt").to("cpu", quantized_model.dtype)
generated_ids = quantized_model.generate(**inputs, max_new_tokens=128, cache_implementation="static")
output_text = tokenizer.batch_decode(
generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False
)
print(output_text)3. تكميم طبقات مختلفة باستخدام إعدادات تكميم مختلفة (باستخدام التعبيرات النمطية)
يمكننا أيضًا استخدام تعبيرات نمطية (regex) لتحديد الإعدادات لجميع الوحدات التي تحتوي على module_fqn يتطابق مع التعبير النمطي، حيث يجب أن تبدأ جميع التعبيرات النمطية بـ re:، فعلى سبيل المثال re:layers\..*\.gate_proj سيتطابق مع جميع الطبقات مثل layers.0.gate_proj. راجع هنا للتوثيق.
import logging
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TorchAoConfig
# Configure logging to see warnings and debug information
logging.basicConfig(
level=logging.INFO, format="%(name)s - %(levelname)s - %(message)s"
)
# Enable specific loggers that might contain the serialization warnings
logging.getLogger("transformers").setLevel(logging.INFO)
logging.getLogger("torchao").setLevel(logging.INFO)
logging.getLogger("safetensors").setLevel(logging.INFO)
logging.getLogger("huggingface_hub").setLevel(logging.INFO)
model_id = "facebook/opt-125m"
from torchao.quantization import (
Float8DynamicActivationFloat8WeightConfig,
Int4WeightOnlyConfig,
IntxWeightOnlyConfig,
PerRow,
PerAxis,
FqnToConfig,
Float8Tensor,
Int4TilePackedTo4dTensor,
IntxUnpackedToInt8Tensor,
)
float8dyn = Float8DynamicActivationFloat8WeightConfig(granularity=PerRow())
int4wo = Int4WeightOnlyConfig(int4_packing_format="tile_packed_to_4d")
intxwo = IntxWeightOnlyConfig(weight_dtype=torch.int8, granularity=PerAxis(0))
qconfig_dict = {
# highest priority
"model.decoder.layers.3.self_attn.q_proj": int4wo,
"model.decoder.layers.3.self_attn.k_proj": int4wo,
"model.decoder.layers.3.self_attn.v_proj": int4wo,
# vllm
"model.decoder.layers.3.self_attn.qkv_proj": int4wo,
"re:model\.decoder\.layers\..+\.self_attn\.q_proj": float8dyn,
"re:model\.decoder\.layers\..+\.self_attn\.k_proj": float8dyn,
"re:model\.decoder\.layers\..+\.self_attn\.v_proj": float8dyn,
# this should not take effect and we'll fallback to _default
# since no full mach (missing `j` in the end)
"re:model\.decoder\.layers\..+\.self_attn\.out_pro": float8dyn,
# vllm
"re:model\.decoder\.layers\..+\.self_attn\.qkv_proj": float8dyn,
"_default": intxwo,
}
quant_config = FqnToConfig(qconfig_dict)
quantization_config = TorchAoConfig(quant_type=quant_config)
quantized_model = AutoModelForCausalLM.from_pretrained(
model_id,
device_map="auto",
torch_dtype=torch.bfloat16,
quantization_config=quantization_config,
)
print("quantized model:", quantized_model)
tokenizer = AutoTokenizer.from_pretrained(model_id)
for i in range(12):
if i == 3:
assert isinstance(quantized_model.model.decoder.layers[i].self_attn.q_proj.weight, Int4TilePackedTo4dTensor)
assert isinstance(quantized_model.model.decoder.layers[i].self_attn.k_proj.weight, Int4TilePackedTo4dTensor)
assert isinstance(quantized_model.model.decoder.layers[i].self_attn.v_proj.weight, Int4TilePackedTo4dTensor)
else:
assert isinstance(quantized_model.model.decoder.layers[i].self_attn.q_proj.weight, Float8Tensor)
assert isinstance(quantized_model.model.decoder.layers[i].self_attn.k_proj.weight, Float8Tensor)
assert isinstance(quantized_model.model.decoder.layers[i].self_attn.v_proj.weight, Float8Tensor)
assert isinstance(quantized_model.model.decoder.layers[i].self_attn.out_proj.weight, IntxUnpackedToInt8Tensor)
# Manual Testing
prompt = "What are we having for dinner?"
print("Prompt:", prompt)
inputs = tokenizer(
prompt,
return_tensors="pt",
).to(quantized_model.device, quantized_model.dtype)
# setting temperature to 0 to make sure result deterministic
generated_ids = quantized_model.generate(**inputs, max_new_tokens=128, temperature=0)
correct_output_text = tokenizer.batch_decode(
generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False
)
print("Response:", correct_output_text[0][len(prompt) :])
# Load model from saved checkpoint
reloaded_model = AutoModelForCausalLM.from_pretrained(
save_to,
device_map=torch.accelerator.current_accelerator(),
torch_dtype=torch.bfloat16,
# quantization_config=quantization_config,
)
generated_ids = reloaded_model.generate(**inputs, max_new_tokens=128, temperature=0)
output_text = tokenizer.batch_decode(
generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False
)
print("Response:", output_text[0][len(prompt) :])
assert(correct_output_text == output_text)التسلسل
إن حفظ النموذج المُكمَّم باستخدام save_pretrained (بصيغة safetensors) مدعوم فقط لـ torchao >= v0.15. أما بالنسبة لأي إصدار أدنى من ذلك، فلا يمكن الحفظ يدوياً إلا كنقاط تفتيش غير آمنة بصيغة .bin باستخدام torch.save.
# torchao >= 0.15
output_dir = "llama3-8b-int4wo-128"
quantized_model.save_pretrained("llama3-8b-int4wo-128")# torchao >= 0.15
USER_ID = "your_huggingface_user_id"
REPO_ID = "llama3-8b-int4wo-128"
quantized_model.push_to_hub(f"{USER_ID}/llama3-8b-int4wo-128")
tokenizer.push_to_hub(f"{USER_ID}/llama3-8b-int4wo-128")# torchao < 0.15 -> unsafe serialization
filename = "llama3-8b-int4wo-128/pytorch_model.bin"
torch.save(quantized_model.state_dict(), filename)تحميل النماذج المُكمّاة
يعتمد تحميل نموذج مُكمَّم على مخطط الكمّ. ففي مخططات الكمّ مثل int8 وfloat8، يمكنك كمّ النموذج على أي جهاز وتحميله على أي جهاز أيضاً. يوضح المثال أدناه كمّ النموذج على وحدة المعالجة المركزية (CPU) ثم تحميله على CUDA أو XPU.
import torch
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
from torchao.quantization import Int8WeightOnlyConfig
quant_config = Int8WeightOnlyConfig(group_size=128)
quantization_config = TorchAoConfig(quant_type=quant_config)
# Load and quantize the model
quantized_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B-Instruct",
dtype="auto",
device_map="cpu",
quantization_config=quantization_config
)
# save the quantized model
output_dir = "llama-3.1-8b-torchao-int8"
quantized_model.save_pretrained(output_dir)
# reload the quantized model
reloaded_model = AutoModelForCausalLM.from_pretrained(
output_dir,
device_map="auto",
dtype=torch.bfloat16
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
input_text = "What are we having for dinner?"
input_ids = tokenizer(input_text, return_tensors="pt").to(reloaded_model.device.type)
output = reloaded_model.generate(**input_ids, max_new_tokens=10)
print(tokenizer.decode(output[0], skip_special_tokens=True))
في حالة int4، لا يمكن تحميل النموذج إلا على نفس الجهاز الذي تم فيه تكميمه، لأن الترتيب (layout) محدد لكل جهاز. يوضح المثال أدناه كيفية تكميم النموذج وتحميله على وحدة المعالجة المركزية (CPU).
import torch
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
from torchao.quantization import Int4WeightOnlyConfig
from torchao.quantization.quantize_.workflows import Int4PackingFormat
quant_config = Int4WeightOnlyConfig(group_size=128, int4_packing_format=Int4PackingFormat.PLAIN_INT32)
quantization_config = TorchAoConfig(quant_type=quant_config)
# Load and quantize the model
quantized_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B-Instruct",
dtype="auto",
device_map="cpu",
quantization_config=quantization_config
)
# save the quantized model
output_dir = "llama-3.1-8b-torchao-int4-cpu"
quantized_model.save_pretrained(output_dir)
# reload the quantized model
reloaded_model = AutoModelForCausalLM.from_pretrained(
output_dir,
device_map="cpu",
dtype=torch.bfloat16
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
input_text = "What are we having for dinner?"
input_ids = tokenizer(input_text, return_tensors="pt").to(reloaded_model.device.type)
output = reloaded_model.generate(**input_ids, max_new_tokens=10)
print(tokenizer.decode(output[0], skip_special_tokens=True))
الموارد
لإحساس أفضل بالأداء المتوقع، اطّلع على المعايير المرجعية لعدة نماذج باستخدام واجهات CUDA وXPU. كما يمكنك تشغيل الكود أدناه لإجراء اختبار أداء للنموذج بنفسك.
from torch._inductor.utils import do_bench_using_profiling
from typing import Callable
def benchmark_fn(func: Callable, *args, **kwargs) -> float:
"""Thin wrapper around do_bench_using_profiling"""
no_args = lambda: func(*args, **kwargs)
time = do_bench_using_profiling(no_args)
return time * 1e3
MAX_NEW_TOKENS = 1000
print("int4wo-128 model:", benchmark_fn(quantized_model.generate, **input_ids, max_new_tokens=MAX_NEW_TOKENS, cache_implementation="static"))
bf16_model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto", dtype=torch.bfloat16)
output = bf16_model.generate(**input_ids, max_new_tokens=10, cache_implementation="static") # auto-compile
print("bf16 model:", benchmark_fn(bf16_model.generate, **input_ids, max_new_tokens=MAX_NEW_TOKENS, cache_implementation="static"))للحصول على أفضل أداء، يمكنك استخدام الإعدادات الموصى بها عن طريق استدعاء
torchao.quantization.utils.recommended_inductor_config_setter()
راجع تقنيات التكميم المتاحة الأخرى لمزيد من الأمثلة والتوثيق.
المشكلات
If you encounter any issues with the Transformers integration, please open an issue on the Transformers repository. For issues directly related to torchao, please open an issue on the torchao repository.
Update on GitHub