尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PEFT 中的 QALoRA:面向 GPTQ 量化模型的量化感知低秩适配训练完全指南

PEFT 中的 QALoRA:面向 GPTQ 量化模型的量化感知低秩适配训练完全指南 PEFT 中的 QALoRA面向 GPTQ 量化模型的量化感知低秩适配训练完全指南【免费下载链接】peft PEFT: State-of-the-art Parameter-Efficient Fine-Tuning.项目地址: https://gitcode.com/gh_mirrors/pe/peft本文以 PEFT 仓库中的 QALoRA 官方示例文档 为主体结合 QALoRA 训练脚本 与 QALoRA 变体源码实现系统讲解量化感知低秩适配Quantization-Aware Low-Rank Adaptation的原理、配置参数、完整训练流程与部署方法。读完本文后你将掌握如何在 GPTQ 4bit 量化模型上以 QALoRA 进行高效微调理解qalora_group_size对内存与精度权衡的影响并能在消费级 GPU 上完成从量化缓存、训练到加载推理的完整闭环。一、QALoRA 是什么量化感知 LoRA 的核心思想QALoRA 是 Low-Rank Adaptation 的量化感知版本其目标是对已经量化如 GPTQ 4bit的大语言模型进行高效微调。传统 LoRA 虽然只训练低秩增量矩阵但基座模型通常仍以全精度驻留显存而 QALoRA 直接作用于量化权重之上通过输入特征池化input feature pooling与专用分组技术进一步降低可训练参数的计算与内存开销从而让原本超出消费级 GPU 容量的大模型变得可微调。在 PEFT 中QALoRA 通过LoraConfig的两个参数开启use_qalorabool默认False启用 QALoRA。当前仅在 GPTQ 量化路径下实现且目前只支持 linear 层参数定义见 src/peft/tuners/lora/config.pyqalora_group_sizeint默认16池化分组大小。输入特征按该大小分组求平均每组产生一个池化特征决定维度压缩比例。qalora_group_size控制内存/性能权衡取值越小压缩率越高、可训练参数越少但可能影响模型质量取值越大质量保持越好、开销越高。该参数仅在使用use_qaloraTrue时生效。适用前提PEFT 中的 QALoRA 目前只支持 GPTQ 量化模型官方文档明确说明 In PEFT it only works for GPTQ。若使用 bitsandbytes 的 NF4 量化即常见 QLoRA 场景use_qalora不适用。二、快速上手基于 PEFT API 的 QALoRA 训练官方文档给出的最小可运行示例如下加载一个 GPTQ 4bit 量化模型配置 QALoRA 适配器用Trainer完成语言模型微调import torch from peft import LoraConfig, get_peft_model from transformers import AutoTokenizer, AutoModelForCausalLM, Trainer from datasets import load_dataset # Load a quantized model (example with GPTQ quantization) model AutoModelForCausalLM.from_pretrained( TheBloke/Llama-2-7b-GPTQ, revisiongptq-4bit-32g-actorder_True, device_mapauto ) tokenizer AutoTokenizer.from_pretrained(TheBloke/Llama-2-7b-GPTQ) dataset load_dataset(timdettmers/openassistant-guanaco, splittrain) # Configure QALoRA parameters lora_config LoraConfig( use_qaloraTrue, qalora_group_size8, r16, lora_alpha32, target_modules[q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj], lora_dropout0.05, ) # Create the PEFT model peft_model get_peft_model(model, lora_config) # Set up trainer and train trainer Trainer( modelpeft_model, train_datasetdataset, argsTrainingArguments( per_device_train_batch_size1, gradient_accumulation_steps4, num_train_epochs3, learning_rate3e-4, output_dirqalora-llama-2-7b ), data_collatorDataCollatorForLanguageModeling(tokenizer, mlmFalse), ) trainer.train() peft_model.save_pretrained(qalora-llama-2-7b)关键要点只需两个额外参数在普通 LoRA 配置基础上设置use_qaloraTrue并指定qalora_group_size其余r、lora_alpha、target_modules等均遵循标准 LoRA 语义qalora_group_size的取值约束从源码看池化要求in_features % qalora_group_size 0即目标线性层的输入维度必须能被分组大小整除否则初始化时直接抛出ValueError校验逻辑见 QALoraLinearVariant.init保存的仍是标准 PEFT 适配器save_pretrained产出的权重与配置文件与 LoRA 适配器格式一致部署时用PeftModel.from_pretrained加载即可。三、完整 CLI 训练流程qalora_gptq_finetuning.py全参数解析仓库提供了一键式训练脚本 examples/qalora_finetuning/qalora_gptq_finetuning.py相比手写代码它额外解决了两个工程问题自动检测与量化缓存load_or_quantize_model()会先尝试加载--base_model遍历模块检查是否已具备 GPTQ 属性qweight/qzeros。若模型尚未量化则用GPTQConfig(bits4, datasetc4, tokenizer..., group_size128, desc_actFalse, symFalse)进行量化并把结果缓存到./quantized_models/目录避免重复执行昂贵的量化过程见 脚本 L23-L105完整训练管线数据集 tokenizepad 位置 label 置-100做损失掩码、DataCollatorForLanguageModeling、TrainingArguments组装、Trainer训练与push_to_hub发布。3.1 命令行示例最简用法指定自定义分组大小脚本默认值为 32python examples/qalora_finetuning/qalora_gptq_finetuning.py \ --base_model TheBloke/Llama-2-7b-GPTQ \ --use_qalora \ --qalora_group_size 32官方文档给出的完整示例13B 模型python qalora_gptq_finetuning.py \ --base_model TheBloke/Llama-2-13b-GPTQ \ --output_dir PATH_TO_OUTPUT_DIR \ --batch_size 1 \ --num_epochs 3 \ --learning_rate 3e-4 \ --cutoff_len 512 \ --use_qalora \ --qalora_group_size 32 \ --eval_step 10 \ --save_step 100 \ --device auto \ --lora_r 16 \ --lora_alpha 32 \ --lora_dropout 0.05 \ --lora_target_modules q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj \ --push_to_hub3.2 全参数表以脚本 argparse 默认值为准参数类型默认值说明--base_modelstrTheBloke/Llama-2-7b-GPTQ基座模型名称或路径未量化时自动 GPTQ 量化并缓存--data_pathstrtimdettmers/openassistant-guanaco数据集名称或本地路径需含text字段--data_splitstr数据集 split 名称--output_dirstr./qalora_output微调模型输出目录--bitsint4量化位宽GPTQ 缓存量化时使用--batch_sizeint4每设备训练 batch size--num_epochsint1训练轮数--learning_ratefloat3e-4学习率--cutoff_lenint128最大序列长度truncation/padding 目标长度--use_qaloraflag强制为True启用 QALoRA脚本内即使不显式传入也默认开启--qalora_group_sizeint32池化分组大小控制压缩率与内存/精度权衡--lora_rint8LoRA 秩--lora_alphaint16LoRA 缩放系数 alpha--lora_dropoutfloat0.05LoRA dropout--lora_target_modulesstr全部 7 个投影层逗号分隔的目标模块列表默认q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj--eval_stepint100评估/日志步长同时作为logging_steps--save_stepint500检查点保存步长--devicestrauto训练设备auto时自动探测当前加速器--push_to_hubflagFalse是否将结果推送到 Hub需HF_TOKEN环境变量此外脚本内部固定了若干训练配置gradient_accumulation_steps16、warmup_steps100、weight_decay0.01、fp16True、save_total_limit2见 脚本 L239-L256即实际全局 batch size 为batch_size × 16。3.3 测试用例验证GPU 端到端测试 test_causal_lm_training_gptq_qalora 验证了完整的 QALoRA 训练链路GPTQ 量化加载 →LoraConfig(r16, lora_alpha32, target_modules[q_proj,v_proj], use_qaloraTrue, qalora_group_size32)→get_peft_model→Trainer训练 →save_pretrained。该测试注释明确指出若适配器配置不正确训练会直接失败因此它同时是 QALoRA 功能可用性的回归保障。四、源码深潜QALoRA 在 PEFT 中的实现原理4.1 GPTQ 层的分发路径PEFT 中 QALoRA 并不是一个独立的 tuner而是 LoRA 的一种变体LoraVariant仅在 GPTQ 量化线层路径中启用。分发逻辑位于 GPTQLoraLinear.resolve_lora_variantdef resolve_lora_variant(self, *, config: LoraConfig, **kwargs) - Optional[LoraVariant]: if config.velora_config is not None: raise ValueError(f{self.__class__.__name__} does not support VeLoRA.) if config.use_dora and config.use_qalora: raise NotImplementedError( fDoRA and QA-LoRA at the same time is not supported for {self.__class__.__name__} (yet). ) elif config.use_dora: variant DoraLinearVariant() elif config.use_qalora: variant QALoraLinearVariant() else: variant None return variant两个值得注意的限制DoRA 与 QALoRA 不可叠加两者同时开启会抛出NotImplementedError模块级分发函数 dispatch_gptq 仅对 GPTQ 的BaseQuantLinear层创建GPTQLoraLinear包装层这正是官方文档In PEFT it only works for GPTQ的源码依据。4.2 init压缩 lora_A 的输入维度QALoraLinearVariant.init 做了三件事整除性校验in_features % qalora_group_size ! 0时抛错——这是选择分组大小时必须遵守的硬约束把qalora_group_size注册为该层的额外参数名使其随适配器一同序列化重建更窄的lora_A原来形状为(r, in_features)的 A 矩阵被替换为nn.Linear(in_features // group_size, r, biasFalse)。也就是说QALoRA 的 lora_A 参数数量是标准 LoRA 的1/group_size这正是其量化感知、低开销的来源——它直接匹配池化后特征的维度而不是在完整维度上做投影。4.3 forward输入池化 低秩增量前向逻辑 QALoraLinearVariant.forward 是理解 QALoRA 的关键x_dropped dropout(x) if module.training and not isinstance(dropout, nn.Identity) else x orig_shape x_dropped.shape # Reshape to 2D if len(orig_shape) 2: x_flat x_dropped.view(-1, module.in_features) else: x_flat x_dropped batch_size, in_features x_flat.shape pooled_features in_features // group_size x_pooled x_flat.view(batch_size, pooled_features, group_size).mean(dim2) x_pooled_scaled x_pooled * pooled_features # LoRA computation delta x_pooled_scaled lora_A_weight.t() lora_B_weight.t() * scaling # Reshape back if len(orig_shape) 2: delta delta.view(orig_shape[:-1] (delta.size(-1),)) return result delta拆解这一过程的数学含义分组平均将输入向量x按group_size切块每块求均值得到in_features / group_size维的池化向量幅度恢复乘以pooled_features即组数进行缩放使池化后特征的整体幅度与原特征同量级——求平均会天然衰减数值尺度这一步补偿了该衰减低秩映射池化特征经过压缩版lora_A维度已除以 group_size与标准lora_B相乘乘以scaling即lora_alpha / r后叠加到量化层的输出result上。因此每层的增量计算delta P(x) · A · B · scalingP 为分组池化算子只依赖in_features / group_size维的中间表示A 矩阵更小、矩阵乘法更廉价。分组大小越大池化越温和参数与计算越接近标准 LoRA分组越小参数越省但输入信息的丢弃越多——这与文档中smaller values use less memory but may affect performance的表述相互印证。4.4 merge 路径为什么 QALoRA 无法直接合并QALoraLinearVariant的get_delta_weight、merge_safe、merge_unsafe、unmerge全部抛出NotImplementedError(QALoRA for GPTQ layers does not support ...)见 variants.py L531-L545。原因很直接QALoRA 的增量定义在池化后的输入空间上不存在一个普通的B·A权重差可以线性合并进全精度权重矩阵。官方文档对与量化模型合并的实现细节也明确说明当前实现与原 QA-LoRA 论文的 beta shift直接修改量化权重不同PEFT 的路线是将量化模型先反量化到全精度在反量化模型上合并 QALoRA 适配器权重若仍需量化则对合并后的模型重新执行 GPTQ 量化。这意味着合并过程需要容纳完整反量化模型的显存并额外付出一次重量化的计算成本大模型在消费级硬件上可能不可行。官方因此建议多数场景下保留量化基座模型 QALoRA 适配器分离部署用PeftModel.from_pretrained()组合加载从而在整个部署管线中保持量化的内存效率优势。五、训练后的加载与推理QALoRA 训练产出的适配器与标准 PEFT 模型用法完全一致。官方文档的加载示例from peft import PeftModel, PeftConfig from transformers import AutoModelForCausalLM, AutoTokenizer # Load the base quantized model base_model AutoModelForCausalLM.from_pretrained( TheBloke/Llama-2-7b-GPTQ, device_mapauto ) tokenizer AutoTokenizer.from_pretrained(TheBloke/Llama-2-7b-GPTQ) # Load the PEFT adapter peft_model_id YOUR_HF_REPO model PeftModel.from_pretrained(base_model, peft_model_id) # Generate text input_text Hello, Im a language model inputs tokenizer(input_text, return_tensorspt).to(model.device) outputs model.generate(**inputs, max_length100) print(tokenizer.decode(outputs[0], skip_special_tokensTrue))由于推理时 QALoRA 前向路径同样经过输入池化加载侧无需任何特殊处理只要基座模型仍是 GPTQ 量化层PeftModel.from_pretrained会按adapter_config.json中记录的use_qalora与qalora_group_size自动重建压缩版lora_A并挂接变体前向。六、QALoRA 与标准 LoRA 的对比官方文档总结了 QALoRA 相对标准 LoRA 的优势内存效率QALoRA 直接作用于量化模型相比标准 LoRA 可减少 60%–70% 的内存占用标准 LoRA 需要全精度基座驻留硬件可及性使得 13B、70B 级别模型可在消费级 GPU 上微调而这些模型用标准 LoRA 难以负担性能保持尽管存在量化QALoRA 在许多任务上可接近全精度 LoRA 的效果。结合源码还可以补充两点差异其一QALoRA 的lora_A参数量按1/group_size收缩在低秩场景下训练开销更小其二QALoRA 与 DoRA 互斥、且不支持权重合并工程上需要以适配器叠加方式使用而不能像普通 LoRA 那样merge_and_unload后直接导出全精度模型。七、参考文献官方文档附带的引用信息article{dettmers2023qlora, title{QLoRA: Efficient Finetuning of Quantized LLMs}, author{Dettmers, Tim and Pagnoni, Artidoro and Holtzman, Ari and Zettlemoyer, Luke}, journal{arXiv preprint arXiv:2305.14314}, year{2023} } article{xu2023qalora, title{QA-LoRA: Quantization-Aware Low-Rank Adaptation of Large Language Models}, author{Xu, Yuhui and Liu, Lingxi and Rao, Longhui and Zhao, Teng and Xiong, Zhiwei and Gao, Mingkui}, journal{arXiv preprint arXiv:2309.14717}, year{2023} }延伸阅读仓库内相关路径QALoRA 示例文档examples/qalora_finetuning/README.mdQALoRA 训练脚本examples/qalora_finetuning/qalora_gptq_finetuning.pyQALoRA 变体实现src/peft/tuners/lora/variants.pyGPTQ LoRA 层与分发src/peft/tuners/lora/gptq.py参数定义与文档src/peft/tuners/lora/config.pyGPU 端到端测试tests/test_gpu_examples.py【免费下载链接】peft PEFT: State-of-the-art Parameter-Efficient Fine-Tuning.项目地址: https://gitcode.com/gh_mirrors/pe/peft创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表