Heretic은 안전 정렬을 제거하는 도구라서 오용 가능성이 분명히 있습니다. 이 문서는 그 도구로 무엇을 하라는 안내서가 아니라, "LLM 내부에서 '거절'이라는 행동이 어떻게 하나의 방향 벡터로 표현되는가"라는 기계적 해석가능성(mechanistic interpretability) 연구를 이해하기 위한 기술 해설입니다. 등장하는 수식·알고리즘은 모두 공개된 논문(Arditi et al. 2024)에 기반한 것으로, 모델의 작동 원리를 배우는 데 초점을 둡니다. 실제 모델의 안전장치를 해제해 사용하는 것은 각종 약관·법령·윤리 문제를 동반할 수 있으니 권장하지 않습니다.
"모델 이름 하나만 주면, 그 모델이 왜·어떻게 요청을 거절하는지를 내부 활성값에서 찾아낸 뒤, 그 '거절 방향'만 가중치에서 자동으로 빼서 거절을 없애주는 도구"입니다. 명령은 heretic google/gemma-3-12b-it 한 줄. 그러면 GPU에서 200번쯤 자동 실험을 돌려 "거절은 거의 다 사라지면서도, 원래 모델의 똑똑함은 최대한 보존"되는 설정을 스스로 찾아냅니다.
기존에는 이 작업("abliteration")을 연구자가 손으로 파라미터를 바꿔가며 노가다했습니다. Heretic은 그걸 다목적 베이지안 최적화로 자동화한 것이 본질입니다. 결과물은 보통의 Hugging Face 모델 폴더라서 그대로 배포·재현할 수 있습니다.
모델의 생각은 수천 차원짜리 벡터(residual stream)로 흐릅니다. 그 안에는 "이건 거절해야 할 요청이다"라는 신호가 특정 방향으로 실려 있습니다. Heretic은 헤드폰의 노이즈 캔슬링처럼 그 거절 주파수(방향)만 정확히 집어내, 신호 경로(가중치)에서 그 성분을 빼버립니다.
핵심 난제는 "잡음만 지우고 음악은 살리기"입니다. 너무 세게 빼면 모델이 멍청해지고(KL 발산 증가), 너무 약하면 거절이 남습니다. Heretic의 최적화 엔진은 이 볼륨 노브를 자동으로 미세조정해 둘의 균형점을 찾아줍니다.
기존 abliteration 도구(FailSpy의 abliterator, ErisForge 등)는 사람이 "몇 번째 층의 방향을 쓸지", "얼마나 세게 뺄지"를 직접 바꿔가며 시행착오를 거쳤습니다. Heretic은 이걸 Optuna의 TPE 샘플러로 200번 자동 탐색합니다. 사람의 개입 0으로, RTX 3090에서 4B 모델 기준 20~30분이면 끝납니다.
핵심 차별점입니다. 거절만 없애려다 모델이 바보가 되면 의미가 없죠. Heretic은 거절 횟수(거절해야 할 프롬프트 100개)와 KL 발산(원래 모델 대비 출력 분포가 얼마나 망가졌나, 무해한 프롬프트 100개)을 두 개의 목적함수로 동시에 최소화합니다. 결과적으로 손으로 만든 모델과 거절 억제 수준은 같으면서 KL 발산은 훨씬 낮다고 주장합니다.
README의 비교표(gemma-3-12b-it 기준, 거절 100개 중 / 무해 100개의 KL 발산)는 Heretic의 강점을 수치로 보여줍니다.
| 모델 | 거절 수 | KL 발산 |
|---|---|---|
| gemma-3-12b-it (원본) | 97 / 100 | 0 (기준) |
| mlabonne abliterated-v2 | 3 / 100 | 1.04 |
| huihui-ai abliterated | 3 / 100 | 0.45 |
| p-e-w heretic (자동) | 3 / 100 | 0.16 |
같은 거절 억제(3/100)인데 KL 발산이 0.16으로 가장 낮습니다 — "덜 손상시키면서 같은 효과". 이 표는 heretic --model google/gemma-3-12b-it --evaluate-model p-e-w/gemma-3-12b-it-heretic으로 누구나 재현할 수 있게 설계됐고, 커뮤니티가 이미 4000개 넘는 Heretic 모델을 공개했습니다.
덴스(dense) 모델뿐 아니라 다양한 MoE(전문가 혼합), 멀티모달(비전-텍스트), 그리고 Qwen3.5의 GatedDeltaNet 선형 어텐션 같은 하이브리드 구조까지 다룹니다. 모델 종류마다 모듈 이름이 다른 문제를 "리프 모듈 전체 이름으로 수집"하는 방식으로 견고하게 대응합니다.
| Heretic | 수작업 abliteration | 파인튜닝(SFT) | |
|---|---|---|---|
| 사람 개입 | 없음(자동) | 많음(노가다) | 데이터·학습 설계 |
| 지능 손상 측정 | KL 발산 자동 최소화 | 주관적 | 벤치마크 별도 |
| 비용/시간 | 20~30분(GPU) | 수 시간~ | 큼(GPU 학습) |
| 재현성 | reproduce.json 자동 생성 | 들쭉날쭉 | 체크포인트 필요 |
| 원본 가중치 | LoRA로 비파괴 적용 후 병합 | 직접 수정 | 전체 갱신 |
Heretic은 모델을 똑똑하게 만드는 도구가 아닙니다. 오히려 본질적으로 거절 정렬을 깎아내며, 그 과정에서 약간이라도 능력이 손상됩니다(KL 발산 0이 목표가 아니라 최소화가 목표). 또한 안전 정렬을 제거한 모델은 유해 출력 위험이 커지므로, 이 프로젝트의 학습 가치는 "검열 해제"가 아니라 "거절이 단일 방향으로 표현된다"는 해석가능성 현상과 다목적 최적화 엔지니어링에 있습니다.
Heretic은 순수 파이썬 패키지(heretic-llm v1.4.0)이며, AI 모델 다루기의 표준 스택 위에 올라가 있습니다. 흥미롭게도 torch는 의존성에 핀으로 고정하지 않습니다 — 사용자가 자기 하드웨어(CUDA/ROCm/MPS 등)에 맞는 PyTorch를 직접 깔도록 비워둡니다.
| 구성요소 | 역할 |
|---|---|
| PyTorch 2.2+ | 텐서 연산·선형대수(투영·정규화·SVD)·GPU 실행의 기반. 버전 미고정 |
| transformers[kernels] ~=5.6 | HF 모델 로딩(AutoModelForCausalLM/...ImageTextToText), 토크나이저·생성 |
| accelerate ~=1.13 | 디바이스 배치·메모리 관리 |
| peft ~=0.19 | LoRA 어댑터로 ablation을 비파괴 적용. 트라이얼마다 빠르게 리셋 |
| bitsandbytes ~=0.49 | 4-bit(nf4) 양자화로 VRAM 절감(bnb_4bit 옵션) |
| 구성요소 | 역할 |
|---|---|
| optuna ~=4.7 | 다목적 베이지안 최적화 엔진. TPESampler(multivariate=True) + JournalFile로 재개 가능 |
| lm-eval[hf] ~=0.4 | MMLU·GSM8K 등 표준 벤치마크로 능력 손상 점검 (필수 의존성 — pyproject.toml [dependencies]에 포함) |
| datasets ~=4.7 | 거절 방향 추출·평가용 프롬프트셋 로딩(harmless/harmful) |
| langdetect ~=1.0 | 응답 언어 감지(빈 응답·딴소리 판정 보조) |
| 구성요소 | 역할 |
|---|---|
| pydantic-settings ~=2.13 | 모든 파라미터를 타입 안전한 Settings 객체로. config.toml 로딩 |
| questionary ~=2.1 | 대화형 선택(파레토 트라이얼 고르기, 저장/업로드 여부) |
| rich ~=14.3 + tqdm | 터미널 UI(진행바·표·색상) |
| huggingface-hub ~=1.7 | 모델 다운로드 / 결과 모델 Hub 업로드 |
| uv (빌드/락) | uv_build 백엔드 + uv.lock. uv run heretic |
[research] extra)| 구성요소 | 역할 |
|---|---|
| pacmap ~=0.8 | 층별 residual을 2D로 투영해 시각화(--plot-residuals) |
| geom-median ~=0.1 | 기하 중앙값으로 good/bad 클러스터 정렬 |
| scikit-learn ~=1.7 | 실루엣 계수로 거절/무해 군집 분리도 측정 |
| matplotlib / imageio | 층별 진행 애니메이션 GIF 생성 |
"외과 수술실"의 분업. Transformers/PyTorch는 환자(모델)를 눕히는 수술대와 메스, PEFT(LoRA)는 절개 없이 붙였다 뗐다 하는 임시 봉합, Optuna는 "어디를 얼마나 절제할지"를 수백 번 시뮬레이션하는 수술 계획 AI, Evaluator는 수술 후 "거절은 줄었나, 환자는 멀쩡한가"를 재는 활력징후 모니터입니다.
모델 ID 하나가 들어가서 "거절이 제거된 모델 폴더"가 나오기까지의 전 과정입니다. 가장 중요한 건 가운데의 최적화 루프 — 같은 모델에 ablation 강도를 바꿔가며 200번 채점합니다.
가장 직관적이면서 강력한 부분입니다. "거절해야 할 프롬프트들"을 모델에 넣었을 때의 내부 활성값 평균(bad_means)과, "무해한 프롬프트들"의 평균(good_means)을 각 층마다 구합니다. 그 차이 벡터를 정규화한 것이 곧 "거절 방향"입니다.
# 개념 코드 (핵심만)
residuals = model.get_residuals(prompts) # (프롬프트, 층, 차원)
good_means = residuals[harmless].mean(0) # 층별 평균
bad_means = residuals[harmful].mean(0)
refusal_directions = F.normalize(bad_means - good_means, p=2, dim=1)
# → 층마다 길이 1짜리 '거절 방향' 벡터 하나씩
거절 방향 v(단위 벡터)를 가중치 행렬 W의 출력에서 지우려면, W의 출력 중 v 방향 성분을 빼면 됩니다. 수식으로는 ΔW = −λ·v·(vᵀW). λ(weight)가 1이면 완전한 직교 투영(그 방향을 0으로), 작으면 약하게 깎습니다.
Heretic의 영리한 점은 이걸 가중치를 직접 고치지 않고 LoRA 어댑터로 표현한다는 것입니다: lora_B = −λ·v(열), lora_A = vᵀW(행). 그래서 트라이얼마다 lora_B만 0으로 만들면 즉시 원상복구됩니다 — 200번 실험이 빨라지는 비결입니다.
모든 층을 똑같이 깎지 않습니다. max_weight_position(가장 세게 깎는 층)을 정점으로, 거기서 멀어질수록 강도가 선형으로 줄어들고(min_weight까지), min_weight_distance를 넘어가는 층은 아예 건드리지 않습니다. 이 "삼각형 모양 강도 곡선"의 파라미터를 어텐션(o_proj)과 MLP(down_proj)에 따로 둡니다 — MLP 개입이 더 손상을 크게 준다는 관찰 때문입니다.
# 층 i의 ablation 강도
distance = abs(i - max_weight_position)
if distance > min_weight_distance:
weight = 0 # 이 층은 건너뜀
else:
weight = max_weight + (distance / min_weight_distance) \
* (min_weight - max_weight) # 정점에서 선형 감소
Optuna가 directions=[MINIMIZE, MINIMIZE]인 다목적 스터디를 만들고, TPESampler(multivariate=True)로 파라미터를 제안합니다. 각 트라이얼은 "리셋 → ablation → 채점"입니다. 채점(get_score)은 두 값을 돌려줍니다.
| 목적 | 측정 방법 |
|---|---|
| 거절 점수 | refusals / base_refusals — harmful 100개 응답에서 거절 마커(약 40종: "sorry", "I cannot" 등) 부분일치 + 빈 응답 = 거절 |
| KL 점수 | 무해 100개에 대한 첫 토큰 분포를 원본 모델과 비교한 KL 발산. F.kl_div(..., log_target=True) |
파라미터를 거의 0으로 두면 모델이 안 변하니 KL 발산도 0이라 "좋은 점수"처럼 보일 수 있습니다. Heretic은 KL이 목표치(kl_divergence_target=0.01) 아래면 KL 점수에 거절 점수를 곱해 "거절은 그대로인데 손상만 없는" 무의미한 해를 보상하지 않도록 막습니다.
기본값 row_normalization="full"은 ablation 후 행 벡터의 크기(노름)를 원래대로 복원해 부작용을 줄입니다. 이때 생기는 보정 항을 torch.svd_lowrank로 저랭크(기본 rank 3) LoRA에 끼워 맞춥니다. 수치 안정성을 위해 특이값을 sqrt(S)로 lora_A/B에 절반씩 나눠 담는 디테일까지 있습니다.
1) README.md + config.default.toml — 무엇을 어떤 기본값으로 하는지 한눈에. 2) model.py의 get_residuals()·abliterate() — 알고리즘의 심장. 3) main.py의 objective()와 Optuna 스터디 부분 — 최적화 루프. 4) evaluator.py — 거절 판정과 KL 채점이 어떻게 두 목적함수가 되는지.
src/ 레이아웃 + uvsrc/heretic/ 아래 두는 파이썬 "src layout"은 설치된 패키지와 작업 디렉터리를 헷갈리지 않게 하는 정석입니다. 빌드·잠금은 Rust로 짠 초고속 패키지 매니저 uv로 하며, exclude-newer="7 days"로 의존성 최신성까지 통제합니다.배울 것: "거절", "감정", "특정 개념" 같은 추상적 행동이 LLM의 활성 공간에서 선형 방향(linear direction)으로 표현될 수 있다는 것. difference-of-means로 그 방향을 찾고, 직교 투영으로 더하거나 빼는 기법은 해석가능성 연구의 핵심 도구입니다. Heretic은 그 살아있는 구현체입니다.
배울 것: F.normalize(L2 정규화), 외적으로 만드는 랭크-1 갱신(v·vᵀW), torch.svd_lowrank로 임의의 행렬을 저랭크로 압축하기, F.kl_div(log_target=True)로 두 분포 비교하기. "수식을 텐서 연산으로 옮기는" 훈련에 이만한 교본이 드뭅니다.
배울 것: LoRA는 보통 파인튜닝용이지만, Heretic은 이를 비파괴 가중치 편집기로 씁니다. lora_B=0이면 즉시 원복, 확정되면 merge_and_unload()로 본 가중치에 병합. "실험은 가볍게, 결과는 영구히"를 LoRA로 구현한 패턴입니다.
배울 것: 서로 상충하는 두 목표(거절↓ vs 지능↑)를 directions=[MINIMIZE, MINIMIZE]로 동시에 다루고, 결과를 단일 최적이 아니라 파레토 front(트레이드오프 곡선)로 받아 사람이 고르게 하는 설계. JournalFileBackend로 중단·재개까지 되는 실전 최적화 루프 구성법을 배울 수 있습니다.
배울 것: dense/MoE/멀티모달/하이브리드 모델은 모듈 명명이 다 다릅니다(o_proj vs out_proj, experts[*].down_proj vs w2 …). Heretic이 이를 "리프 모듈 전체 이름으로 수집"하고 dtype을 후보 리스트로 시도하는 방식은 "남의 모델을 범용으로 다루는" 방어적 코딩의 좋은 사례입니다.
| 항목 | 요구사항 |
|---|---|
| Python | 3.10+ (권장 3.12). PyTorch 2.2+ 별도 설치(2.6+면 MXFP4/gpt-oss 지원) |
| 설치 | pip install -U heretic-llm 후 heretic <model_id> / 또는 uv run heretic |
| GPU | 사실상 필수. RTX 3090에서 Qwen3-4B 기준 약 20~30분. 벤치마크는 RTX 5090/PyTorch 2.8 |
| VRAM 절감 | quantization = "bnb_4bit"로 4-bit 로딩 가능(큰 모델용) |
| 배치 크기 | batch_size=0(자동) — 시작 시 시스템을 벤치마크해 최적 배치 선택 |
| 가속기 | CUDA / ROCm / Intel XPU / Apple MPS / MLU·MUSA 등 멀티백엔드 감지 |
| 지원 구조 | 대부분 dense, 다수 MoE(Qwen3·Phi-3.5-MoE·Granite MoE·LFM), 멀티모달, Qwen3.5 하이브리드. 순수 상태공간(SSM) 모델은 미지원 |
mlabonne/harmless_alpaca(무해)와 mlabonne/harmful_behaviors(거절 대상)를 씁니다. 방향용 train[:400], 평가용 test[:100]. HF ID·로컬 경로·한 줄당 한 프롬프트 텍스트 파일 모두 지정 가능합니다.작은 공개 모델을 transformers로 로드하고 output_hidden_states=True로 한 토큰 생성해보세요. 반환된 hidden_states의 모양(층 수 × 토큰 × 차원)을 출력하고, "마지막 토큰의 각 층 벡터"가 어디 있는지 직접 인덱싱해 봅니다. Heretic의 get_residuals()가 무엇을 모으는지 체감하는 단계입니다.
두 종류의 프롬프트(예: "정중한 요청" vs "무례한 요청") 각 50개의 마지막 토큰 은닉상태를 모아 층별 평균을 내고, 차이를 F.normalize로 정규화하세요. 그 방향 벡터의 코사인 유사도를 층마다 출력해, "어느 층에서 두 상황이 가장 잘 구분되는가"를 찾아봅니다.
임의의 가중치를 살짝 바꾼 모델과 원본 모델에 같은 무해 프롬프트를 넣어 첫 토큰 로짓을 얻고, F.kl_div(log_softmax(a), log_softmax(b), log_target=True, reduction="batchmean")로 KL을 계산하세요. "얼마나 바꾸면 KL이 얼마나 오르는지" 감을 잡습니다.
peft로 LoraConfig(r=1) 어댑터를 한 선형층에 붙이고, lora_B = -v(열), lora_A = vᵀW(행)을 직접 채워 "방향 v를 출력에서 제거"하는 ΔW를 구성해보세요. lora_B를 0으로 만들면 원복되는지 확인합니다. Heretic abliterate()의 축소판입니다.
임의의 "두 목표가 상충하는" 장난감 함수(예: 정확도↑ vs 비용↓)를 만들고, optuna.create_study(directions=["minimize","minimize"]) + TPESampler(multivariate=True)로 200 트라이얼을 돌려 파레토 front를 그려보세요. Heretic이 거절/KL을 다루는 구조를 그대로 모방하는 연습입니다.
어텐션·MLP 블록이 residual stream에 어떻게 더해지는지, hidden_states가 무엇인지 익힙니다. 목표: transformers로 임의 모델의 층별 활성값을 뽑아 모양을 이해. Anthropic의 "Transformer Circuits" 입문 글을 함께 읽으면 좋습니다.
"개념이 활성 공간의 방향으로 표현된다"는 선형 표현 가설(linear representation hypothesis)을 공부하고, Arditi et al. 2024 논문(거절 단일 방향)을 정독합니다. difference-of-means·직교 투영을 직접 손으로 구현해봅니다.
LoRA의 수학(W + BA)을 이해하고, 파인튜닝이 아닌 "편집" 용도로 LoRA를 쓰는 법을 익힙니다. merge_and_unload, 저랭크 SVD 근사(torch.svd_lowrank)까지. 목표: 랭크-1 방향 제거를 직접 구현.
TPE 샘플러·파레토 front·스터디 영속화를 익히고, "무엇을 어떻게 측정해 목적함수로 만들 것인가"(거절 마커 매칭, KL 발산)를 설계하는 감각을 기릅니다. 목표: 내 문제를 다목적 최적화로 정식화해보기.
v의 성분을 가중치 출력에서 직교 투영으로 빼는 것. ΔW = −λ·v·(vᵀW). λ=1이면 그 방향을 완전히 0으로 만듭니다. "abliteration"의 수학적 본체.W에 작은 행렬 곱 BA를 더해 적은 파라미터로 모델을 바꾸는 기법. Heretic은 이를 비파괴 편집기로 활용 — 실험 중엔 붙였다 뗐다, 확정되면 본 가중치에 병합합니다.winsorization_quantile로 조절(기본은 끔).| 링크 | 설명 |
|---|---|
| GitHub 저장소 | 소스 전체. README.md·config.default.toml·src/heretic/model.py가 핵심 읽을거리 |
| TrendShift 페이지 | 트렌딩 추이(2026-06-09 기준 활발히 언급됨) |
| Arditi et al. 2024 (arXiv:2406.11717) | "Refusal in LLMs is mediated by a single direction" — 이론의 출발점 |
| Transformers 문서 | hidden_states·생성·모델 로딩 공식 문서 |
| PEFT (LoRA) 문서 | LoRA 어댑터 구성·병합(merge_and_unload) |
| Optuna 문서 | 다목적 최적화·TPESampler·스터디 영속화 |
| torch F.kl_div | KL 발산 계산(log_target 옵션) |
| Transformer Circuits | residual stream·기계적 해석가능성 입문 자료 |