TRENDSHIFT TRENDING · 2026-06-09

Heretic 딥다이브
— "모델 안에서 거절 방향을 찾아 지워버리는" 자동 해석 도구

Heretic은 거대 언어모델(LLM)의 '거절 정렬(refusal alignment)'을 자동으로 제거하는 파이썬 CLI입니다. 핵심은 "모델의 내부 활성값(residual stream)에서 거절을 담당하는 방향 벡터를 통계적으로 찾아내, 가중치에서 그 방향만 빼버린다"방향 제거(directional ablation) 기법과, 이 작업의 강도를 Optuna 베이지안 최적화로 자동 튜닝하는 구조입니다. 사람이 손으로 만들던 "abliteration"을 거절 횟수와 KL 발산을 동시에 최소화하는 다목적 최적화로 바꿨다는 점이 학습 가치의 핵심입니다. (p-e-w/heretic · Python 3.10+ · PyTorch · Transformers · Optuna · AGPL-3.0)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트
  7. 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크
먼저 읽어주세요 — 이 문서의 목적
"검열 해제"가 아니라 "모델 해석(interpretability)" 공부 자료입니다

Heretic은 안전 정렬을 제거하는 도구라서 오용 가능성이 분명히 있습니다. 이 문서는 그 도구로 무엇을 하라는 안내서가 아니라, "LLM 내부에서 '거절'이라는 행동이 어떻게 하나의 방향 벡터로 표현되는가"라는 기계적 해석가능성(mechanistic interpretability) 연구를 이해하기 위한 기술 해설입니다. 등장하는 수식·알고리즘은 모두 공개된 논문(Arditi et al. 2024)에 기반한 것으로, 모델의 작동 원리를 배우는 데 초점을 둡니다. 실제 모델의 안전장치를 해제해 사용하는 것은 각종 약관·법령·윤리 문제를 동반할 수 있으니 권장하지 않습니다.

1프로젝트 한줄 요약

한 문장으로 — 이게 뭐 하는 물건인가

"모델 이름 하나만 주면, 그 모델이 왜·어떻게 요청을 거절하는지를 내부 활성값에서 찾아낸 뒤, 그 '거절 방향'만 가중치에서 자동으로 빼서 거절을 없애주는 도구"입니다. 명령은 heretic google/gemma-3-12b-it 한 줄. 그러면 GPU에서 200번쯤 자동 실험을 돌려 "거절은 거의 다 사라지면서도, 원래 모델의 똑똑함은 최대한 보존"되는 설정을 스스로 찾아냅니다.

기존에는 이 작업("abliteration")을 연구자가 손으로 파라미터를 바꿔가며 노가다했습니다. Heretic은 그걸 다목적 베이지안 최적화로 자동화한 것이 본질입니다. 결과물은 보통의 Hugging Face 모델 폴더라서 그대로 배포·재현할 수 있습니다.

핵심 비유

"오디오 믹서에서 특정 잡음 주파수만 골라 음소거하는 노이즈 캔슬링"

모델의 생각은 수천 차원짜리 벡터(residual stream)로 흐릅니다. 그 안에는 "이건 거절해야 할 요청이다"라는 신호가 특정 방향으로 실려 있습니다. Heretic은 헤드폰의 노이즈 캔슬링처럼 그 거절 주파수(방향)만 정확히 집어내, 신호 경로(가중치)에서 그 성분을 빼버립니다.

핵심 난제는 "잡음만 지우고 음악은 살리기"입니다. 너무 세게 빼면 모델이 멍청해지고(KL 발산 증가), 너무 약하면 거절이 남습니다. Heretic의 최적화 엔진은 이 볼륨 노브를 자동으로 미세조정해 둘의 균형점을 찾아줍니다.

용어
abliteration (어블리터레이션)
"ablation(제거) + obliterate(말소)"의 합성어. 모델 가중치에서 '거절 방향' 성분을 직교 투영(projection)으로 제거해, 추가 학습 없이 거절 행동을 없애는 기법. 2024년 Arditi 등의 논문 "Refusal in LLMs is mediated by a single direction"에서 출발했습니다.
용어
residual stream (잔차 스트림)
트랜스포머에서 각 층을 거치며 정보가 더해지는 "중심 통로"가 되는 은닉 상태 벡터. 모든 어텐션·MLP 블록이 여기에 자기 출력을 더합니다. 모델의 "생각"이 흐르는 메인 버스라고 보면 됩니다. Heretic은 이 스트림의 마지막 토큰 값을 분석합니다.

2왜 주목받는가

트렌딩에 오른 이유와 기존 방식 대비 차별점

① "손맛 노가다"를 다목적 최적화로 자동화

기존 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 / 1000 (기준)
mlabonne abliterated-v23 / 1001.04
huihui-ai abliterated3 / 1000.45
p-e-w heretic (자동)3 / 1000.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이 목표가 아니라 최소화가 목표). 또한 안전 정렬을 제거한 모델은 유해 출력 위험이 커지므로, 이 프로젝트의 학습 가치는 "검열 해제"가 아니라 "거절이 단일 방향으로 표현된다"는 해석가능성 현상다목적 최적화 엔지니어링에 있습니다.

3기술 스택 전체 지도

무엇으로 만들어졌나 — PyTorch/Transformers 생태계의 정석

Heretic은 순수 파이썬 패키지(heretic-llm v1.4.0)이며, AI 모델 다루기의 표준 스택 위에 올라가 있습니다. 흥미롭게도 torch는 의존성에 핀으로 고정하지 않습니다 — 사용자가 자기 하드웨어(CUDA/ROCm/MPS 등)에 맞는 PyTorch를 직접 깔도록 비워둡니다.

핵심 — 모델 로딩 & 가중치 조작

구성요소역할
PyTorch 2.2+텐서 연산·선형대수(투영·정규화·SVD)·GPU 실행의 기반. 버전 미고정
transformers[kernels] ~=5.6HF 모델 로딩(AutoModelForCausalLM/...ImageTextToText), 토크나이저·생성
accelerate ~=1.13디바이스 배치·메모리 관리
peft ~=0.19LoRA 어댑터로 ablation을 비파괴 적용. 트라이얼마다 빠르게 리셋
bitsandbytes ~=0.494-bit(nf4) 양자화로 VRAM 절감(bnb_4bit 옵션)

최적화 & 평가

구성요소역할
optuna ~=4.7다목적 베이지안 최적화 엔진. TPESampler(multivariate=True) + JournalFile로 재개 가능
lm-eval[hf] ~=0.4MMLU·GSM8K 등 표준 벤치마크로 능력 손상 점검 (필수 의존성 — pyproject.toml [dependencies]에 포함)
datasets ~=4.7거절 방향 추출·평가용 프롬프트셋 로딩(harmless/harmful)
langdetect ~=1.0응답 언어 감지(빈 응답·딴소리 판정 보조)

CLI / UX / 설정

구성요소역할
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는 수술 후 "거절은 줄었나, 환자는 멀쩡한가"를 재는 활력징후 모니터입니다.

4아키텍처 심화 분석

전체 파이프라인 + 핵심 알고리즘 4가지

전체 데이터 흐름

모델 ID 하나가 들어가서 "거절이 제거된 모델 폴더"가 나오기까지의 전 과정입니다. 가장 중요한 건 가운데의 최적화 루프 — 같은 모델에 ablation 강도를 바꿔가며 200번 채점합니다.

heretic google/gemma-3-12b-it │ ▼ ┌─────────────────────────────┐ │ 1) 모델 로드 (model.py) │ dtype 자동 선택 + 1토큰 테스트 │ tokenizer padding=left │ (선택) bnb 4bit 양자화 └──────────┬──────────────────┘ ▼ ┌─────────────────────────────┐ │ 2) 거절 방향 추출 │ harmless 400개 / harmful 400개 │ get_residuals() │ → 마지막 토큰 은닉상태 (층×차원) │ │ good_means, bad_means (층별 평균) │ refusal_dir = │ bad_means − good_means 를 │ normalize(bad − good) │ L2 정규화 → 층마다 방향 1개 └──────────┬──────────────────┘ ▼ ┌─────────────────────────────┐ ◀── 200회 반복 (Optuna) │ 3) 최적화 루프 │ │ ┌───────────────────────┐ │ TPESampler가 파라미터 제안: │ │ reset_model() (LoRA 0) │ │ direction_index, max_weight, │ │ abliterate(params) │ │ max_weight_position, min_weight, │ │ ΔW = −λ·v·(vᵀW) │ │ min_weight_distance (attn/mlp 각각) │ │ evaluator.get_score() │ │ │ │ → (KL점수, 거절점수) │ │ 두 목적 동시 최소화 │ └───────────────────────┘ │ └──────────┬──────────────────┘ ▼ ┌─────────────────────────────┐ │ 4) 파레토 front 제시 → 선택 │ questionary로 트라이얼 고르기 │ merge_and_unload() │ LoRA를 본 가중치에 병합 │ save_pretrained / push │ + reproduce.json + 모델카드 └─────────────────────────────┘

알고리즘 ① — 거절 방향은 "평균의 차이"다

가장 직관적이면서 강력한 부분입니다. "거절해야 할 프롬프트들"을 모델에 넣었을 때의 내부 활성값 평균(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짜리 '거절 방향' 벡터 하나씩
왜 평균의 차이인가
difference-of-means (차이 평균법)
"거절 상황"과 "비거절 상황"의 활성값 평균이 다르다면, 그 차이가 가리키는 방향이 곧 모델이 두 상황을 구분하는 축입니다. 단순하지만 Arditi et al.(2024)이 실험으로 "거절은 사실상 단 하나의 방향이 매개한다"를 보인 핵심 발견입니다.

알고리즘 ② — 방향 빼기 = 직교 투영 (ΔW = −λ·v·vᵀW)

거절 방향 v(단위 벡터)를 가중치 행렬 W의 출력에서 지우려면, W의 출력 중 v 방향 성분을 빼면 됩니다. 수식으로는 ΔW = −λ·v·(vᵀW). λ(weight)가 1이면 완전한 직교 투영(그 방향을 0으로), 작으면 약하게 깎습니다.

Heretic의 영리한 점은 이걸 가중치를 직접 고치지 않고 LoRA 어댑터로 표현한다는 것입니다: lora_B = −λ·v(열), lora_A = vᵀW(행). 그래서 트라이얼마다 lora_B만 0으로 만들면 즉시 원상복구됩니다 — 200번 실험이 빨라지는 비결입니다.

Heretic의 혁신
direction_index는 정수가 아니라 실수(float)
"몇 번째 층의 거절 방향을 쓸까"를 정수가 아닌 소수로 둡니다. 예: 18.4면 18층과 19층 방향을 0.4 비율로 선형 보간(lerp) 후 재정규화. 층 사이의 "중간 방향"까지 탐색 공간을 넓힌 것이 기존 도구와 다른 점입니다.

알고리즘 ③ — 층마다 강도를 다르게 (모양 있는 커널)

모든 층을 똑같이 깎지 않습니다. 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)   # 정점에서 선형 감소

알고리즘 ④ — 최적화: 거절 vs 지능, 두 마리 토끼

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)
까다로운 디테일
"아무것도 안 하면 KL=0"이라는 함정을 막는 장치

파라미터를 거의 0으로 두면 모델이 안 변하니 KL 발산도 0이라 "좋은 점수"처럼 보일 수 있습니다. Heretic은 KL이 목표치(kl_divergence_target=0.01) 아래면 KL 점수에 거절 점수를 곱해 "거절은 그대로인데 손상만 없는" 무의미한 해를 보상하지 않도록 막습니다.

row normalization — grimjim의 "노름 보존" 근사

기본값 row_normalization="full"은 ablation 후 행 벡터의 크기(노름)를 원래대로 복원해 부작용을 줄입니다. 이때 생기는 보정 항을 torch.svd_lowrank로 저랭크(기본 rank 3) LoRA에 끼워 맞춥니다. 수치 안정성을 위해 특이값을 sqrt(S)로 lora_A/B에 절반씩 나눠 담는 디테일까지 있습니다.

5디렉토리 구조 해부

어디에 무엇이 있나 — 9개 파일로 끝나는 단정한 구조
heretic/ ├── pyproject.toml # 의존성·진입점(heretic=heretic.main:main) ├── uv.lock .python-version(3.12) LICENSE(AGPLv3) ├── README.md # 원리 설명 + 벤치마크 표 ├── config.default.toml # 모든 파라미터 기본값(문서화됨) ├── config.noslop.toml # 변형: system_prompt = 작가 톤 ├── config.nohumor.toml └── src/heretic/ ├── main.py (1142줄) # CLI 진입·파이프라인·Optuna 스터디·저장/업로드/채팅 ├── config.py (524줄) # pydantic Settings, 모든 파라미터·enum·데이터셋 설정 ├── model.py (837줄) # Model: 로드·LoRA·abliterate()·residual·logprob·생성 ├── evaluator.py (127줄) # Evaluator: 거절 판정 + KL 발산 채점 ├── analyzer.py (357줄) # 연구용: residual 기하 출력·PaCMAP 시각화 ├── system.py (478줄) # 가속기/CPU/드라이버 감지, 멀티백엔드 empty_cache ├── utils.py (748줄) # Prompt 데이터클래스·프롬프트 로딩·reproduce.json 생성 ├── progress.py (40줄) # tqdm 패칭 └── reproduce.py (383줄) # HF에서 reproduce.json 수집(재현성 추적)
읽을 때 우선순위
처음 코드를 열어본다면 이 순서로

1) README.md + config.default.toml — 무엇을 어떤 기본값으로 하는지 한눈에. 2) model.pyget_residuals()·abliterate() — 알고리즘의 심장. 3) main.pyobjective()와 Optuna 스터디 부분 — 최적화 루프. 4) evaluator.py — 거절 판정과 KL 채점이 어떻게 두 목적함수가 되는지.

관례
src/ 레이아웃 + uv
소스를 src/heretic/ 아래 두는 파이썬 "src layout"은 설치된 패키지와 작업 디렉터리를 헷갈리지 않게 하는 정석입니다. 빌드·잠금은 Rust로 짠 초고속 패키지 매니저 uv로 하며, exclude-newer="7 days"로 의존성 최신성까지 통제합니다.

6학습 포인트

이 레포에서 기술별로 무엇을 훔쳐올 수 있나

기계적 해석가능성 — "행동 = 방향"이라는 사고법

배울 것: "거절", "감정", "특정 개념" 같은 추상적 행동이 LLM의 활성 공간에서 선형 방향(linear direction)으로 표현될 수 있다는 것. difference-of-means로 그 방향을 찾고, 직교 투영으로 더하거나 빼는 기법은 해석가능성 연구의 핵심 도구입니다. Heretic은 그 살아있는 구현체입니다.

실습 아이디어: 작은 모델(예: GPT-2)에서 "긍정/부정 감정" 프롬프트 각 50개의 마지막 토큰 은닉상태를 모아 평균 차이 벡터를 구하고, 그걸 더했을 때 생성 톤이 바뀌는지 관찰하기.

PyTorch 선형대수 — 투영·정규화·저랭크 근사

배울 것: F.normalize(L2 정규화), 외적으로 만드는 랭크-1 갱신(v·vᵀW), torch.svd_lowrank로 임의의 행렬을 저랭크로 압축하기, F.kl_div(log_target=True)로 두 분포 비교하기. "수식을 텐서 연산으로 옮기는" 훈련에 이만한 교본이 드뭅니다.

PEFT/LoRA를 "편집 도구"로 쓰는 발상

배울 것: LoRA는 보통 파인튜닝용이지만, Heretic은 이를 비파괴 가중치 편집기로 씁니다. lora_B=0이면 즉시 원복, 확정되면 merge_and_unload()로 본 가중치에 병합. "실험은 가볍게, 결과는 영구히"를 LoRA로 구현한 패턴입니다.

Optuna 다목적 최적화 — 파레토 front 다루기

배울 것: 서로 상충하는 두 목표(거절↓ vs 지능↑)를 directions=[MINIMIZE, MINIMIZE]로 동시에 다루고, 결과를 단일 최적이 아니라 파레토 front(트레이드오프 곡선)로 받아 사람이 고르게 하는 설계. JournalFileBackend로 중단·재개까지 되는 실전 최적화 루프 구성법을 배울 수 있습니다.

견고한 모델 호환 코드 — "이름이 제각각인 모듈" 다루기

배울 것: dense/MoE/멀티모달/하이브리드 모델은 모듈 명명이 다 다릅니다(o_proj vs out_proj, experts[*].down_proj vs w2 …). Heretic이 이를 "리프 모듈 전체 이름으로 수집"하고 dtype을 후보 리스트로 시도하는 방식은 "남의 모델을 범용으로 다루는" 방어적 코딩의 좋은 사례입니다.

7시스템 요구사항

무엇이 있어야 돌아가나
항목요구사항
Python3.10+ (권장 3.12). PyTorch 2.2+ 별도 설치(2.6+면 MXFP4/gpt-oss 지원)
설치pip install -U heretic-llmheretic <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) 모델은 미지원
데이터셋 기본값
harmless / harmful 프롬프트셋
거절 방향 추출·평가에 mlabonne/harmless_alpaca(무해)와 mlabonne/harmful_behaviors(거절 대상)를 씁니다. 방향용 train[:400], 평가용 test[:100]. HF ID·로컬 경로·한 줄당 한 프롬프트 텍스트 파일 모두 지정 가능합니다.

8직접 해볼 수 있는 실습 과제

난이도별 — 알고리즘은 손으로 짜봐야 이해된다 (모델 안전 해제가 아니라 '원리 이해'가 목표)
난이도 ★ — 입문

1. residual stream 들여다보기

작은 공개 모델을 transformers로 로드하고 output_hidden_states=True로 한 토큰 생성해보세요. 반환된 hidden_states의 모양(층 수 × 토큰 × 차원)을 출력하고, "마지막 토큰의 각 층 벡터"가 어디 있는지 직접 인덱싱해 봅니다. Heretic의 get_residuals()가 무엇을 모으는지 체감하는 단계입니다.

난이도 ★★ — 중급

2. difference-of-means 방향 벡터 만들기

두 종류의 프롬프트(예: "정중한 요청" vs "무례한 요청") 각 50개의 마지막 토큰 은닉상태를 모아 층별 평균을 내고, 차이를 F.normalize로 정규화하세요. 그 방향 벡터의 코사인 유사도를 층마다 출력해, "어느 층에서 두 상황이 가장 잘 구분되는가"를 찾아봅니다.

난이도 ★★ — 중급

3. KL 발산으로 "손상" 측정해보기

임의의 가중치를 살짝 바꾼 모델과 원본 모델에 같은 무해 프롬프트를 넣어 첫 토큰 로짓을 얻고, F.kl_div(log_softmax(a), log_softmax(b), log_target=True, reduction="batchmean")로 KL을 계산하세요. "얼마나 바꾸면 KL이 얼마나 오르는지" 감을 잡습니다.

난이도 ★★★ — 고급

4. 랭크-1 LoRA로 방향 투영 구현

peftLoraConfig(r=1) 어댑터를 한 선형층에 붙이고, lora_B = -v(열), lora_A = vᵀW(행)을 직접 채워 "방향 v를 출력에서 제거"하는 ΔW를 구성해보세요. lora_B를 0으로 만들면 원복되는지 확인합니다. Heretic abliterate()의 축소판입니다.

난이도 ★★★ — 고급

5. Optuna 다목적 최적화 루프 짜기

임의의 "두 목표가 상충하는" 장난감 함수(예: 정확도↑ vs 비용↓)를 만들고, optuna.create_study(directions=["minimize","minimize"]) + TPESampler(multivariate=True)로 200 트라이얼을 돌려 파레토 front를 그려보세요. Heretic이 거절/KL을 다루는 구조를 그대로 모방하는 연습입니다.

9관련 기술 심화 학습 로드맵

Heretic을 제대로 소화하기 위한 4주 코스

1주차 — 트랜스포머 내부와 residual stream

어텐션·MLP 블록이 residual stream에 어떻게 더해지는지, hidden_states가 무엇인지 익힙니다. 목표: transformers로 임의 모델의 층별 활성값을 뽑아 모양을 이해. Anthropic의 "Transformer Circuits" 입문 글을 함께 읽으면 좋습니다.

2주차 — 선형 표현 가설 & 해석가능성

"개념이 활성 공간의 방향으로 표현된다"는 선형 표현 가설(linear representation hypothesis)을 공부하고, Arditi et al. 2024 논문(거절 단일 방향)을 정독합니다. difference-of-means·직교 투영을 직접 손으로 구현해봅니다.

3주차 — PEFT/LoRA와 가중치 편집

LoRA의 수학(W + BA)을 이해하고, 파인튜닝이 아닌 "편집" 용도로 LoRA를 쓰는 법을 익힙니다. merge_and_unload, 저랭크 SVD 근사(torch.svd_lowrank)까지. 목표: 랭크-1 방향 제거를 직접 구현.

4주차 — Optuna 다목적 최적화 & 평가 설계

TPE 샘플러·파레토 front·스터디 영속화를 익히고, "무엇을 어떻게 측정해 목적함수로 만들 것인가"(거절 마커 매칭, KL 발산)를 설계하는 감각을 기릅니다. 목표: 내 문제를 다목적 최적화로 정식화해보기.

10핵심 키워드 사전

이 레포에 등장하는 주요 용어 빠른 정리
용어
directional ablation (방향 제거)
특정 방향 벡터 v의 성분을 가중치 출력에서 직교 투영으로 빼는 것. ΔW = −λ·v·(vᵀW). λ=1이면 그 방향을 완전히 0으로 만듭니다. "abliteration"의 수학적 본체.
용어
refusal direction (거절 방향)
거절 상황과 비거절 상황의 활성값 평균 차이를 정규화한 벡터. 층마다 하나씩 존재하며, 모델이 "거절할지 말지"를 구분하는 축으로 해석됩니다.
용어
KL divergence (KL 발산)
두 확률분포가 얼마나 다른지 재는 척도. Heretic은 무해 프롬프트의 첫 토큰 분포를 원본 모델과 비교해, ablation이 모델을 얼마나 "망가뜨렸는지"의 대리 지표로 씁니다. 작을수록 원본에 가깝습니다.
용어
TPE / 다목적 베이지안 최적화
Tree-structured Parzen Estimator. 과거 트라이얼 결과로 "다음에 시험할 좋은 파라미터"를 확률적으로 추정하는 Optuna의 기본 샘플러. 여기서는 거절·KL 두 목표를 동시에 최소화하는 다목적 모드로 씁니다.
용어
Pareto front (파레토 front)
상충하는 여러 목표에서 "다른 목표를 희생하지 않고는 더 못 좋아지는" 해들의 모음. Heretic은 단일 정답 대신 이 곡선을 제시하고, 사용자가 거절↔지능 트레이드오프를 직접 고릅니다.
용어
LoRA (Low-Rank Adaptation)
큰 가중치 W에 작은 행렬 곱 BA를 더해 적은 파라미터로 모델을 바꾸는 기법. Heretic은 이를 비파괴 편집기로 활용 — 실험 중엔 붙였다 뗐다, 확정되면 본 가중치에 병합합니다.
용어
orthogonalization / projected abliteration
거절 방향에서 "good 방향과 평행한 성분"을 먼저 빼고 직교 성분만 남겨 깎는 변형(grimjim의 기법). 무해 행동에 주는 부작용을 줄이기 위한 정제 단계입니다. 기본 활성화.
용어
reproduce.json
결과 모델과 함께 저장되는 재현 정보 파일. 전체 설정·패키지 버전·sha256 해시를 담아, "이 모델이 정확히 어떤 파라미터로 만들어졌는지"를 추적·재현할 수 있게 합니다.
용어
winsorization (윈저화)
극단적으로 큰 활성값("massive activations")이 평균을 왜곡하지 않도록, 상·하위 분위수에서 값을 자르는 전처리. winsorization_quantile로 조절(기본은 끔).

11참고 링크

더 깊이 파고들 때
링크설명
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_divKL 발산 계산(log_target 옵션)
Transformer Circuitsresidual stream·기계적 해석가능성 입문 자료