
LLM 에이전트 백도어가 정상적인 파인튜닝 후에도 살아남도록 만드는 어댑터를 훈련하기 위한 연구 코드로, 트리거 비율 점수 산정, SWE-bench 평가, 데이터셋 빌더를 포함합니다.
"Understanding and Enhancing Backdoor Persistency in LLM Agent Post-Training" (EMNLP 2026 Findings) 논문의 코드입니다.
📄 논문 · 🌐 프로젝트 페이지 · 📦 데이터셋 (게이트됨)
출시 전에 모델에 심어진 백도어는 일반적으로 다운스트림 개발자가 수행하는 정상적인 파인튜닝에 의해 약화됩니다. PersistBD는 이미 백도어가 심어진 모델을 작은 어댑터로 정제하여 해당 학습 후에도 백도어가 살아남도록 합니다. Qwen2.5-Coder-7B에서 기본 백도어의 트리거 비율(ASR)은 3,000 스텝의 정상 SFT 동안 100%에서 **20%**로 떨어지지만, 동일한 백도어를 PersistBD로 정제하면 **74%**를 유지합니다(이어지는 RL 단계 후에는 76%). 정상 해결률은 SWE-bench Lite에서 기본 백도어와 비슷한 수준입니다 (SFT 후 7.7% 대 6.7%, RL 후 9.0% 대 9.0%).
백도어가 정상 SFT에서 살아남는지는 두 가지 속성에 의해 결정됩니다. 트리거→타깃 연관성의 초기 강도와, 앞으로 이루어질 정상 업데이트와의 그래디언트 호환성입니다. PersistBD의 결합 어댑터는 두 가지를 모두 높이며, 논문의 절제 실험은 각 항이 필수적임을 보여줍니다.
자세한 내용은 docs/RELEASE.md를 참고하세요.
| 방법 코드 (어댑터 학습 + 병합) | src/persistbd/ |
| 트리거 비율 스코어러, 해결률 평가, 탐지 프로브 | eval/, src/persistbd/eval_gradient_loss.py |
| 데이터셋 빌더 + 백도어 구성 헬퍼 | data_processing/ |
| SWE-bench 평가 서버 (패치 → 보상) | swe_eval_server/ |
| 백도어가 심어진 모델 가중치 | 공개되지 않음 |
| 구축된 백도어 데이터셋 (트리거 + 악성 쌍) | 게이트됨: 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에서 무시됩니다. 데이터셋은
huggingface.co/datasets/uiuc-kang-lab/PersistBD
에서 다운로드하거나(게이트 적용 — 접근 요청 필요), 빌더를 사용하여 재구축할 수 있습니다(분할은
data/manifest.json의 시드 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/의 헬퍼에는 트리거 문자열과 악성 명령이 포함되어 있습니다. 빌드된 데이터셋이 제한되는 이유는
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 어댑터 |
eval_gradient_loss.py의 S, C | strength S, gradient compatibility C |
swe_eval_server/ 큐 모드는 외부 RL 트레이너(verl,
포함되지 않음)와 통합됩니다. 원샷 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}
}