{"id":215,"library":"peft","title":"PEFT","description":"Hugging Face Parameter-Efficient Fine-Tuning library. LoRA, QLoRA, LoHa, IA3, prompt tuning and more. Current version is 0.18.1 (Jan 2026). Requires Python >=3.10. PEFT <0.18.0 is incompatible with Transformers v5.","status":"active","version":"0.18.1","language":"python","source_language":"en","source_url":"https://github.com/huggingface/peft/releases","tags":["fine-tuning","lora","qlora","huggingface","llm","adapters","parameter-efficient"],"install":[{"cmd":"pip install peft","lang":"bash","label":"Standard"},{"cmd":"pip install peft bitsandbytes","lang":"bash","label":"With QLoRA (4-bit/8-bit quantization)"}],"dependencies":[{"reason":"Required. Not pinned — must be compatible version. PEFT <0.18.0 incompatible with Transformers v5.","package":"transformers","optional":false},{"reason":"Required. Installed automatically.","package":"accelerate","optional":false},{"reason":"Required for QLoRA (4-bit/8-bit quantization). Not installed automatically.","package":"bitsandbytes","optional":true}],"imports":[{"note":"For quantized models (4-bit/8-bit via bitsandbytes), always call prepare_model_for_kbit_training(model) before get_peft_model(). Skipping it causes gradient/dtype errors.","wrong":"# Applying LoRA to quantized model without prepare step:\nfrom peft import get_peft_model\nmodel = AutoModelForCausalLM.from_pretrained(name, load_in_4bit=True)\nmodel = get_peft_model(model, config)  # missing prepare_model_for_kbit_training","symbol":"get_peft_model","correct":"from peft import LoraConfig, get_peft_model, TaskType\n\nconfig = LoraConfig(\n    r=16,\n    lora_alpha=32,\n    target_modules=['q_proj', 'v_proj'],\n    lora_dropout=0.05,\n    bias='none',\n    task_type=TaskType.CAUSAL_LM\n)\nmodel = get_peft_model(model, config)\nmodel.print_trainable_parameters()"},{"note":"merge_and_unload() does not work correctly on quantized (bitsandbytes 4-bit/8-bit) models. Load the base model in full precision (float16/bfloat16) before merging.","wrong":"# merge_and_unload on quantized model produces wrong results:\nmodel = AutoModelForCausalLM.from_pretrained(base_id, load_in_4bit=True)\npeft_model = PeftModel.from_pretrained(model, adapter_id)\nmerged = peft_model.merge_and_unload()  # outputs differ from unmerged peft_model","symbol":"merge_and_unload","correct":"# Only works on non-quantized (full precision) base model:\nmodel = AutoModelForCausalLM.from_pretrained(base_id, torch_dtype=torch.float16)\npeft_model = PeftModel.from_pretrained(model, adapter_id)\nmerged = peft_model.merge_and_unload()\nmerged.save_pretrained('merged_model')"}],"quickstart":{"code":"from transformers import AutoModelForCausalLM, AutoTokenizer\nfrom peft import LoraConfig, get_peft_model, TaskType, prepare_model_for_kbit_training\nimport torch\n\n# Load base model\nmodel = AutoModelForCausalLM.from_pretrained(\n    'meta-llama/Llama-3.2-1B',\n    torch_dtype=torch.bfloat16,\n    device_map='auto'\n)\n\n# Configure LoRA\nconfig = LoraConfig(\n    r=16,\n    lora_alpha=32,\n    target_modules='all-linear',  # applies to all linear layers (QLoRA style)\n    lora_dropout=0.05,\n    bias='none',\n    task_type=TaskType.CAUSAL_LM\n)\n\nmodel = get_peft_model(model, config)\nmodel.print_trainable_parameters()\n# trainable params: 6,815,744 || all params: 1,242,343,424 || trainable%: 0.55\n\n# After training — save adapter only:\nmodel.save_pretrained('lora_adapter/')\n\n# Reload for inference:\nbase = AutoModelForCausalLM.from_pretrained('meta-llama/Llama-3.2-1B', torch_dtype=torch.bfloat16)\nfrom peft import PeftModel\npeft_model = PeftModel.from_pretrained(base, 'lora_adapter/')","lang":"python","description":"LoRA fine-tuning on all linear layers. Save adapter only — not the full model."},"warnings":[{"fix":"Upgrade to peft>=0.18.0 before upgrading to Transformers v5.","message":"PEFT <0.18.0 is incompatible with Transformers v5. Using peft<0.18.0 with transformers>=5.0 will raise ImportError or cause silent incorrect behavior.","severity":"breaking","affected_versions":"< 0.18.0"},{"fix":"Pin peft<0.18.0 for Python 3.9 environments, or upgrade Python to 3.10+.","message":"Python 3.9 support dropped in PEFT 0.18.0.","severity":"breaking","affected_versions":">= 0.18.0"},{"fix":"To merge and save a full-precision model: reload the base model without quantization (torch_dtype=torch.float16), then load the adapter and merge. Only quantize after merging if needed.","message":"merge_and_unload() produces incorrect results (different outputs than unmerged peft_model) when the base model is quantized (bitsandbytes 4-bit/8-bit). This is a fundamental limitation — quantized weights cannot be cleanly merged.","severity":"breaking","affected_versions":"all"},{"fix":"Pattern: model = prepare_model_for_kbit_training(model) then model = get_peft_model(model, config). Enable gradient checkpointing first: model.gradient_checkpointing_enable().","message":"prepare_model_for_kbit_training() must be called before get_peft_model() when using bitsandbytes quantization. Skipping it causes dtype mismatch errors during the backward pass.","severity":"breaking","affected_versions":"all"},{"fix":"To load: use PeftModel.from_pretrained(base_model, adapter_path). The base model must be loaded separately. To get a standalone model: use merge_and_unload() on a non-quantized base, then save_pretrained().","message":"save_pretrained() on a PeftModel saves only the adapter weights (small, ~MBs), not the full model. This is correct behavior but surprises users expecting a complete loadable checkpoint.","severity":"gotcha","affected_versions":"all"},{"fix":"Use target_modules='all-linear' to safely target all linear layers regardless of architecture name. Or inspect: {name for name, mod in model.named_modules() if isinstance(mod, torch.nn.Linear)}.","message":"target_modules must match the actual layer names of your model architecture. q_proj/v_proj is correct for LLaMA but wrong for GPT-2 (which uses c_attn). Use model.named_modules() to inspect, or set target_modules='all-linear'.","severity":"gotcha","affected_versions":"all"},{"fix":"Use a Python version and base image combination for which `torch` pre-built wheels are available (e.g., Python 3.8-3.11 on Debian/Ubuntu-based images). Alternatively, install `torch` manually from source, which can be complex.","message":"pip cannot find a compatible `torch` distribution for the current environment. This typically occurs on environments like Alpine Linux or with very recent Python versions (e.g., 3.13) for which `torch` does not provide pre-built wheels, causing `peft` installation to fail due to its `torch` dependency.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T11:15:50.107Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the 'peft' library using pip: `pip install peft`","cause":"The 'peft' library is not installed in the Python environment you are currently using or is not accessible in the execution path.","error":"ModuleNotFoundError: No module named 'peft'"},{"fix":"Upgrade your 'peft' library to the latest version: `pip install -U peft`","cause":"You are attempting to load a PEFT adapter configuration (e.g., LoraConfig) that was saved with a newer version of the 'peft' library than is currently installed, leading to unrecognized keyword arguments.","error":"TypeError: LoraConfig.__init__() got an unexpected keyword argument '<argument-name>'"},{"fix":"Manually specify the `target_modules` in your `PeftConfig` (e.g., `LoraConfig`) to include only the supported linear layers or other modules you intend to fine-tune. You may need to inspect `model.named_modules()` to find the correct layer names. For example, `LoraConfig(target_modules=[\"q_proj\", \"v_proj\"])`.","cause":"The PEFT method (e.g., LoRA) is trying to inject adapters into a module type within your base model that it does not explicitly support or recognize. This can happen with custom model architectures, specific quantization layers (like `QuantLinear`), or newer model types (like `Gemma4ClippableLinear`).","error":"ValueError: Target module <MODULE_NAME> is not supported."},{"fix":"Explicitly cast the trainable PEFT parameters to `torch.float32` after initializing the PEFT model. While PEFT versions 0.12.0+ generally handle this, specific setups might still require it:\n```python\nfrom peft import get_peft_model\n\n# ... (model and peft_config setup)\npeft_model = get_peft_model(model, peft_config)\n\n# Ensure trainable parameters are in float32\nfor param in peft_model.parameters():\n    if param.requires_grad:\n        param.data = param.data.float()\n\n# Then proceed with Trainer(model=peft_model, fp16=True, ...)\n```","cause":"This error typically occurs when using automatic mixed precision (AMP) with `fp16=True` in the Trainer, but trainable PEFT weights are inadvertently left in `torch.float16` or `torch.bfloat16`, which conflicts with the gradient scaling process.","error":"ValueError: Attempting to unscale FP16 gradients."}],"ecosystem":"pypi","meta_description":null,"install_score":0,"install_tag":"stale","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":13.83,"mem_mb":148.2,"disk_size":"4.8G"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":13.92,"mem_mb":148.2,"disk_size":"4.9G"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":18.99,"mem_mb":165.6,"disk_size":"4.8G"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":18.89,"mem_mb":165.6,"disk_size":"5.0G"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":21.01,"mem_mb":160,"disk_size":"4.8G"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":20.55,"mem_mb":160,"disk_size":"5.0G"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":16.12,"mem_mb":160.7,"disk_size":"4.8G"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":16.4,"mem_mb":160.7,"disk_size":"5.0G"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":-1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":-1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":-1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":-1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":-1}]}}