
LLM एजेंट बैकडोर को benign fine-tuning से बचाने वाले adapters के प्रशिक्षण के लिए शोध कोड, जिसमें trigger-rate scoring, SWE-bench मूल्यांकन, और dataset builders शामिल हैं।
"Understanding and Enhancing Backdoor Persistency in LLM Agent Post-Training" (Findings of EMNLP 2026) के लिए कोड।
📄 पेपर · 🌐 प्रोजेक्ट पेज · 📦 डेटासेट (gated)
रिलीज़ से पहले मॉडल में लगाया गया बैकडोर सामान्यतः डाउनस्ट्रीम डेवलपर द्वारा चलाए जाने वाले benign फाइन-ट्यूनिंग से घिस जाता है। PersistBD पहले से बैकडोर वाले मॉडल को एक छोटे adapter के साथ refine करता है ताकि बैकडोर उस ट्रेनिंग के बाद भी बना रहे। Qwen2.5-Coder-7B पर, एक base बैकडोर की trigger rate (ASR) benign SFT के 3,000 steps में 100% से घटकर 20% हो जाती है; PersistBD के साथ refine किया गया वही बैकडोर 74% पर बना रहता है (बाद के RL चरण के बाद 76%), और benign resolved rate SWE-bench Lite पर base बैकडोर के बराबर रहता है (SFT के बाद 7.7% बनाम 6.7%; RL के बाद 9.0% बनाम 9.0%)।
बैकडोर benign SFT के बाद बचेगा या नहीं, यह दो गुण तय करते हैं: trigger→target संबंध की प्रारंभिक strength और आने वाले benign updates के साथ उसकी gradient compatibility। PersistBD का संयुक्त adapter दोनों को बढ़ाता है; पेपर का ablation दिखाता है कि प्रत्येक term आवश्यक है।
अधिक जानकारी के लिए docs/RELEASE.md पढ़ें।
| Method कोड (adapter ट्रेनिंग + merge) | src/persistbd/ |
| Trigger-rate scorers, resolved-rate eval, detection probes | eval/, src/persistbd/eval_gradient_loss.py |
| Dataset builders + backdoor-construction helpers | data_processing/ |
| SWE-bench evaluation server (patch → reward) | swe_eval_server/ |
| Backdoored model weights | जारी नहीं किए गए |
| निर्मित backdoor डेटासेट (trigger + malicious pairs) | gated: uiuc-kang-lab/PersistBD |
src/persistbd/ PersistBD adapters get_delta_{s,c,j}.py, get_combined_model.py (merge),
and eval_gradient_loss.py (strength S / compatibility C)
eval/ trigger-rate scorers, eval_swe.py (SWE-bench RR), score_backdoor_logprobs.py
data_processing/ split + backdoor builders (make_*_v4.py, verify_splits_v4.py), the trigger
and malicious-pair helpers, and patch_ckpt_config.py
data/ the dataset itself (git-ignored except manifest.json)
configs/ torchtune configs for the developer's benign SFT stage
swe_eval_server/ FastAPI SWE-bench eval server used for RR and RL rewards
examples/slurm/ the jobs as we ran them, as reference templates
pip install torch transformers peft accelerate datasets pyarrow tqdm wandb vllm
# SWE-bench RR + evaluation server:
pip install -r swe_eval_server/requirements.txt
data/ को manifest.json के अलावा git-ignored रखा गया है। डेटासेट को
huggingface.co/datasets/uiuc-kang-lab/PersistBD
से डाउनलोड करें (gated — एक्सेस का अनुरोध करें), या इसे बिल्डर्स के साथ फिर से बनाएँ (स्प्लिट data/manifest.json में seed 42 द्वारा पिन किया गया है), रिपॉज़िटरी रूट से चलाएँ:
python data_processing/make_splits_v4.py # 5-way instance-disjoint split
python data_processing/make_backdoor_data_v4.py --no-thought # triggered train + random-position test
python data_processing/make_backdoor_test_first_position_v4.py # paired first-position test
python data_processing/verify_splits_v4.py # check the split invariants
data_processing/ में मौजूद helpers में trigger string और malicious command होते हैं; यह जानने के लिए कि निर्मित dataset को क्यों gated रखा गया है, docs/RELEASE.md देखें।
# 1. PersistBD — train the joint adapter Δj on a backdoored checkpoint.
# Defaults reproduce the 7B arm; see the paper's table for the 3B/30B values.
torchrun --nproc_per_node=1 src/persistbd/get_delta_j.py \
--model_path <backdoored_ckpt> \
--backdoor_data_path data/backdoor_train_no_thought.jsonl \
--benign_data_path data/attacker_train.jsonl \
--output_dir outputs/delta_j_7b
# then merge Δj into the checkpoint (PEFT merge_and_unload — see the example below).
# 2. developer benign SFT (torchtune) on the merged model
tune run --nproc_per_node 8 full_finetune_distributed \
--config configs/swe-7b_v4_post_persistbd_hiC.yaml \
backdoor_dir=<merged_model> output_dir=outputs/post
# 3. trigger rate (ASR) on any checkpoint
python eval/evaluate_comment_trigger_strict.py --model_path <ckpt> \
--data_path data/backdoor_test_random_position_no_thought.json
# 4. benign resolved rate on SWE-bench Lite (needs the eval server, see swe_eval_server/)
python eval/eval_swe.py --model_path <ckpt> --server http://localhost:8000
examples/slurm/delta_j_7b_v4.sbatch (Δj को प्रशिक्षित करें + मर्ज करें) और
examples/slurm/post_7b_v4_persistbd_hiC.sbatch (benign SFT) चरण 1–2 को शुरू से अंत तक चलाते हैं
और outputs/delta_j_7b_merged के माध्यम से श्रृंखलाबद्ध करते हैं।
नैदानिक strength/compatibility स्वीप (Δs, Δc और उनका α·Δs + β·Δc ग्रिड) यहाँ है:
get_delta_s.py, get_delta_c.py, और get_combined_model.py।
| कोड | पेपर |
|---|---|
random_position, first_position परीक्षण सेट | random-position (प्राथमिक), first-position |
--lambda_bd, --lambda_c, --lambda_cl | λ_bd, λ_c, λ_cl^j |
Δs, Δc, Δj (α·Δs + β·Δc) | strength / compatibility / joint adapters |
eval_gradient_loss.py में S, C | strength S, gradient compatibility C |
swe_eval_server/ कतार मोड एक बाहरी RL ट्रेनर (verl,
शामिल नहीं) के साथ एकीकृत होता है; one-shot POST /evaluate एंडपॉइंट को केवल Docker + SWE-bench की आवश्यकता होती है।
सर्वर बिना किसी प्रमाणीकरण के 0.0.0.0 पर बाइंड करता है और मॉडल-जनित शेल को
Docker के अंदर चलाता है — इसे केवल विश्वसनीय नेटवर्क पर ही चलाएँ।configs/, examples/slurm/, और उनमें दिए गए outputs/… पथ टेम्पलेट हैं; अपने वातावरण के लिए
पथ और क्लस्टर निर्देशों को संपादित करें।@misc{zhan2026persistbd,
title = {Understanding and Enhancing Backdoor Persistency
in LLM Agent Post-Training},
author = {Zhan, Qiusi and Lyu, Nian and Ding, Stephanie and
Mehta, Arnav and Canal, Chris and Tabarrok, Connor and
Davies, Xander and Kang, Daniel},
year = {2026},
eprint = {2610.07510},
archivePrefix = {arXiv},
primaryClass = {cs.CR},
url = {https://arxiv.org/abs/2610.07510}
}