System Info
peft 0.18.1, transformers 5.0.0, torch 2.10-2.12, reproduced on CPU (macOS), Kaggle T4 (CUDA 12), and RTX 5090 (CUDA 12.8).
Who can help?
@BenjaminBossan
Reproduction
Full investigation with reproducer: meta-pytorch/opacus#820. Short version:
model = AutoModelForCausalLM.from_pretrained("gpt2")
# model NOT moved to device here
model = get_peft_model(model, lora_config)
# third-party library registers per-parameter hooks now (opacus's
# PrivacyEngine in our case, but any hook-registering framework hits this)
# ...
batch = batch.cuda() # only the batch moves; lazy handling materializes
# params at first forward, AFTER hooks were registered
Training then proceeds looking completely healthy. Loss decreases, checkpoints save, and in the DP case the privacy accountant keeps reporting epsilon. The LoRA weights never update: max |Δ| = 0.0 after any number of steps. Moving the model to the device before get_peft_model fixes it. We confirmed this on three independent environments over a five-month investigation (write up: https://imranahamed.substack.com/p/the-dp-lora-silent-corruption-how).
Expected behavior
The root cause isn't a peft bug. It's an ordering hazard between peft's lazy device handling and anything that captures parameter references at wrap time (per parameter hooks, early built optimizers). But peft is the layer that can see the hazard forming, and get_peft_model already warns on several usage hazards (double wrapping, renamed base models, adapter name prefix collisions).
Two suggestions, happy to PR either or both:
-
A pre-flight warning in get_peft_model when base-model params are on meta (or _hf_hook.original_devices indicates pending materialization) outside the known device_map inference flows: something like "parameters will be materialized after wrapping; parameter references captured now (hooks, optimizers) may go stale." The meta-device detection pattern already exists in tuners_utils.py and peft_model.py, so this reuses it rather than adding new machinery. Roughly 10-15 lines plus a test.
-
A troubleshooting entry in docs/source/developer_guides/troubleshooting.md documenting the ordering requirement (move to device, then wrap, then register hooks / build optimizers), next to the existing "Bad results from a loaded PEFT model" section.
The condition scoping on (1) needs care to avoid false positives on legitimate device_map="auto" inference loading; I'd propose gating it to training mode wrapping or making it a one-time info-level warning. Open to whatever shape you think fits.
System Info
peft 0.18.1, transformers 5.0.0, torch 2.10-2.12, reproduced on CPU (macOS), Kaggle T4 (CUDA 12), and RTX 5090 (CUDA 12.8).
Who can help?
@BenjaminBossan
Reproduction
Full investigation with reproducer: meta-pytorch/opacus#820. Short version:
Training then proceeds looking completely healthy. Loss decreases, checkpoints save, and in the DP case the privacy accountant keeps reporting epsilon. The LoRA weights never update:
max |Δ| = 0.0after any number of steps. Moving the model to the device beforeget_peft_modelfixes it. We confirmed this on three independent environments over a five-month investigation (write up: https://imranahamed.substack.com/p/the-dp-lora-silent-corruption-how).Expected behavior
The root cause isn't a peft bug. It's an ordering hazard between peft's lazy device handling and anything that captures parameter references at wrap time (per parameter hooks, early built optimizers). But peft is the layer that can see the hazard forming, and
get_peft_modelalready warns on several usage hazards (double wrapping, renamed base models, adapter name prefix collisions).Two suggestions, happy to PR either or both:
A pre-flight warning in
get_peft_modelwhen base-model params are onmeta(or_hf_hook.original_devicesindicates pending materialization) outside the knowndevice_mapinference flows: something like "parameters will be materialized after wrapping; parameter references captured now (hooks, optimizers) may go stale." The meta-device detection pattern already exists intuners_utils.pyandpeft_model.py, so this reuses it rather than adding new machinery. Roughly 10-15 lines plus a test.A troubleshooting entry in
docs/source/developer_guides/troubleshooting.mddocumenting the ordering requirement (move to device, then wrap, then register hooks / build optimizers), next to the existing "Bad results from a loaded PEFT model" section.The condition scoping on (1) needs care to avoid false positives on legitimate
device_map="auto"inference loading; I'd propose gating it to training mode wrapping or making it a one-time info-level warning. Open to whatever shape you think fits.