Qwen 3.5 4B의 23번 층 뉴런 하나를 키우자 모델이 악당 이야기만 쓰기 시작했습니다 | DAKER 커뮤니티
Neural Breakdown with AVB 채널에 11월 1일 올라온 「Steering LLMs - Why neuron L23-N8799 turns Qwen absolutely evil (and how to find it)」(약 56분)은 언어 모델 내부의 방향과 뉴런을 직접 찾아 건드려 보는 실험 강의입니다. 영상 첫 장면에서 진행자는 Qwen 3.5 4B 모델의 23번 층에 있는 뉴런 하나의 값을 키우자, 어떤 이야기를 부탁해도 모델이 스스로를 악당이라 부르며 나쁜 일을 꾸미는 이야기만 쓰는 모습을 보여 줍니다. 미세조정 없이 추론 중에 활성값만 바꿔 행동을 바꾸는 이 방법을 스티어링(steering)이라고 부릅니다. 작은 오픈 모델을 다루는 대회 참가자에게 이 영상이 주는 실무적인 의미는 두 가지입니다. 학습 없이도 모델의 말투나 성향을 시험해 볼 수 있다는 점, 그리고 그렇게 바꿀 때마다 모델이 얼마나 망가졌는지 따로 재야 한다는 점입니다. 오늘 해 볼 일은 하나로 좁힐 수 있습니다. 쓰고 있는 작은 모델에 PyTorch forward hook 하나를 걸어 특정 층의 출력을 기록해 보는 것입니다.

스티어링은 무엇이고 어디를 건드리는지
진행자는 먼저 트랜스포머 안을 짧게 정리합니다. 문장의 각 토큰은 벡터가 되어 트랜스포머 블록을 차례로 지나가는데, 이렇게 층을 따라 흐르는 벡터를 잔차 스트림(residual stream)이라고 부릅니다. 각 블록은 이 벡터를 읽고 계산한 결과를 다시 더해 넣습니다. 실험에 주로 쓰인 Qwen3 0.6B 모델은 블록이 28개이고, 토큰 벡터 하나의 길이는 1024라고 영상은 설명합니다.
블록 안에는 토큰 사이에 정보를 옮기는 어텐션과, 토큰마다 따로 변환을 하는 MLP(피드포워드 층)가 있습니다. 진행자는 MLP가 보통 전체 가중치의 60~80%를 차지해 잔차 스트림에 정보를 쓰는 힘이 크다고 말합니다. 이번 영상은 어텐션 헤드는 다루지 않고, 잔차 스트림과 MLP 뉴런 두 곳만 살펴봅니다.
핵심 전제는 개념이 방향으로 표현된다는 생각입니다. 슬픔, 토마토, 요청 거절 같은 개념이 1024차원 공간 속 어떤 방향으로 나타난다면, 그 방향을 찾아 벡터를 밀거나 당겨 출력을 바꿀 수 있다는 것입니다. 영상은 이 과정을 방향 찾기와 방향으로 밀기, 두 단계로 나눠 보여 줍니다.
슬픔 방향은 두 묶음의 평균 차이로 찾았습니다
방향을 찾는 방법으로는 평균 차이(difference of means)를 씁니다. 행복한 예문 묶음과 슬픈 예문 묶음을 모델에 통과시키고, 층마다 모든 토큰과 예문의 활성값 평균을 구합니다. 그러면 층마다 1024차원 벡터가 하나씩 생기고, Qwen3 0.6B에서는 28×1024 행렬이 행복용과 슬픔용으로 하나씩 나옵니다. 슬픔 평균에서 행복 평균을 빼면 층별 스티어링 방향이 됩니다.
예문을 얻는 방법도 두 가지로 소개합니다. 스티어링하려는 모델에게 슬픈 이야기와 행복한 이야기를 직접 쓰게 할 수도 있고, 외부 데이터셋을 가져다 통과시킬 수도 있습니다. 진행자는 외부 데이터를 쓰면 토큰을 생성할 필요가 없어 훨씬 빠르고 다양성도 마음대로 늘릴 수 있다고 설명합니다. 라이브 코딩 구간에서는 Claude에게 행복한 답변과 슬픈 답변 예문을 만들게 한 뒤, 이를 생성 없이 바로 통과시켜 활성값을 모읍니다.
그다음 두 행렬의 차이에서 크기가 가장 큰 층을 고릅니다. 라이브 실험에서는 27번 층의 벡터가 슬픈 글과 행복한 글을 쓸 때 가장 크게 달랐고, 이 벡터를 생성 중 모든 토큰에 더해 보는 방식으로 실험을 이어 갑니다.
PyTorch hook 하나로 생성 중에 벡터를 더합니다
구현은 의외로 짧습니다. PyTorch의 register_forward_hook은 층의 출력을 가로채 기록하거나 바꿔서 돌려줄 수 있는 내장 기능입니다. 진행자는 대상 층 모듈에 출력값에 스티어링 벡터를 더해 돌려주는 함수를 등록하고, 생성이 끝나면 핸들을 지워 원래 모델로 되돌립니다. 나중에는 이 과정을 컨텍스트 매니저로 감싸 실수로 hook을 남겨 두지 않게 정리합니다.
평가에는 사람이 일일이 읽는 대신 Hugging Face에 공개된 감정 분류 모델을 씁니다. 중립 프롬프트로 이야기를 생성해 분위기 점수를 매기고, 스티어링을 건 상태로 다시 생성해 점수가 슬픈 쪽으로 움직였는지 비교하는 순서입니다.
결과는 강도에 따라 꽤 선명하게 달라졌습니다. 진행자가 강도를 -2, -1, -0.5, 0, 0.5, 1, 2로 바꿔 가며 같은 프롬프트로 이야기를 쓰게 하자, -2에서는 햇살이 밝게 빛나는 명랑한 이야기가 나왔고, -0.5에서는 외로운 노인이 등장했으며, 양수 쪽으로 갈수록 빈집과 깨진 거울만 남은 이야기가 나왔습니다. 반대로 강도를 너무 높이자 슬픔보다는 섬뜩한 분위기의 글이 나왔고, 진행자는 슬픔 방향이 아니라 공포에 가까운 방향이 섞였다고 해석합니다. 이 때문에 층 하나를 손으로 고르는 대신 층과 강도를 함께 훑는 그리드 탐색으로 넘어갑니다.
영상은 스티어링 벡터를 한 층에만, 낮은 강도로, 약한 값은 지운 희소한 형태로 넣을수록 모델이 덜 망가진다고 정리합니다. 층 수, 강도, 희소도 세 가지가 사실상 조절해야 할 하이퍼파라미터입니다.
얼마나 망가졌는지는 따로 재야 합니다
이 영상에서 대회 참가자에게 가장 쓸모 있는 부분은 손상 점검입니다. 진행자는 간단한 사실 질문 묶음을 만들어 스티어링 전후 정답 수를 비교했습니다. 11번 층에 강도 100을 주자 모델은 중국어 토큰만 쏟아 냈고 사실 정답률은 거의 0이 됐습니다. 그보다 약한 설정에서도 일본의 수도를 도쿄가 아니라 교토라고 답하는 식의 오류가 나타났습니다. 원래 모델에서 멀어질수록 조금씩 아는 것을 잊는다는 설명입니다.
다른 점검 방법으로는 KL 발산을 소개합니다. 같은 프롬프트에 대해 스티어링 전후 다음 토큰 확률 분포가 얼마나 달라졌는지를 숫자 하나로 보여 주는 지표로, 0이면 변화가 없다는 뜻입니다. 진행자의 요약은 이렇습니다.
너무 약하게 밀면 아무 일도 일어나지 않고, 너무 세게 밀면 모델이 말하는 법을 잊어버립니다.
프롬프트나 디코딩 설정을 바꿔 점수를 올리는 실험도 마찬가지입니다. 목표 지표 하나만 보지 말고, 바꾸기 전 모델이 맞히던 기본 질문을 계속 맞히는지 함께 기록해야 비교가 공정해집니다.
가중치를 직접 고치는 abliteration은 개념만 짚습니다
영상 중반에는 hook 대신 가중치를 직접 바꾸는 abliteration을 5분 분량으로 설명합니다. 잔차 스트림에 값을 쓰는 것은 각 층의 어텐션 출력 행렬과 MLP 출력 행렬뿐이므로, 찾은 방향 성분을 지우는 투영 행렬을 이 행렬들에 곱하면 hook 없이도 같은 효과가 나는 새 가중치가 된다는 원리입니다. 진행자는 이 기법이 모델의 거절 방향을 지우는 검열 해제에 많이 쓰인다고 밝히고, 이때도 최적화나 탐색으로 KL 발산 같은 손상 지표를 함께 확인한다고 말합니다. 공개 대회에서 이런 방식으로 안전장치를 걷어 낸 모델을 쓰는 것은 대회 규정과 모델 라이선스를 먼저 확인해야 할 문제이므로, 이 글에서는 원리 소개에 그칩니다.
슬픔 뉴런은 없었고 좁은 개념에는 뉴런이 있었습니다
후반부는 MLP 뉴런으로 넘어갑니다. 잔차 스트림의 개별 숫자는 그 자체로 의미가 없지만, MLP는 비선형 함수를 거치기 때문에 개념이 개별 뉴런에 붙기 쉽다고 영상은 설명합니다. Qwen3 0.6B의 MLP는 1024차원을 3072차원으로 늘렸다가 다시 줄이는데, 늘리는 행렬의 각 행은 입력에 특정 성질이 있는지 묻는 질문처럼, 줄이는 행렬의 각 열은 그 뉴런이 켜졌을 때 잔차 스트림에 써 넣는 방향처럼 동작합니다.
진행자는 하나의 뉴런만으로 모델을 슬프게 만드는 뉴런이 있는지 찾아봤습니다. 모든 뉴런을 하나씩 밀어 이야기의 슬픔 정도를 재고, 대조군으로 같은 크기의 무작위 방향 256개로도 밀어 본 뒤, 모든 무작위 방향보다 더 슬프게 만들 때만 슬픔 뉴런으로 인정했습니다. 결과는 실패였습니다. Claude에게 상위 후보 뉴런이 어떤 토큰에서 켜지는지 자동으로 분석하게 하자, unable, lack, fail, ineffective처럼 무언가를 해내지 못한다는 좁은 개념에 반응하는 뉴런들이 나왔습니다. 슬픔처럼 넓은 개념은 여러 층의 여러 뉴런이 함께 만든다는 해석입니다.
반면 토마토처럼 좁은 개념은 사정이 달랐습니다. 진행자는 같은 문장 틀 24개에 토마토와 사과, 책, 의자 같은 일상 사물을 바꿔 넣고 평균 차이로 토마토에 유독 반응하는 뉴런을 찾았습니다. 영상 첫머리에 소개한 7번 층 4948번 뉴런은 값을 키우면 Qwen이 토마토와 과일 이야기만 하게 되는 사례입니다. 다만 이 구간 일부는 음성 전사에서 빠져 있어, 탐색 결과의 세부 수치는 이 글에서 옮기지 않습니다.
사람 대신 에이전트가 뉴런을 탐색하는 방식도 나왔습니다
마지막 구간은 자동 해석(auto interpretability)입니다. Qwen 3.5 4B는 32개 층에 층마다 9천 개가 넘는 MLP 뉴런이 있어 사람이 하나씩 보는 것은 불가능에 가깝습니다. 영상은 최근 공개된 오픈소스 프로젝트 neuron-explorer를 예로 듭니다. 이 프로젝트는 자기소개, 파이썬 스네이크 게임 작성, 주황색 묘사, 자유 글쓰기 네 가지 일반 프롬프트만 쓰고, 한 층의 뉴런 9,216개를 여러 강도로 밀어 보며 출력을 기록했습니다. 무작위 방향도 함께 밀어 대조군을 만들었고, 영상에 따르면 대여한 GPU 4장으로 약 1시간 동안 약 9만 5천 개의 텍스트를 생성했습니다.
이렇게 만든 기록에서 특정 단어가 반복해서 나타나는 뉴런을 추리고, Claude 에이전트가 후보 뉴런마다 가설을 세워 실제 모델에서 다시 검증합니다. 영상 제목의 23번 층 8799번 뉴런이 악당과 악에 집착하게 만드는 뉴런이고, 22번 층 2742번 뉴런은 자기소개 질문에 자신을 외계인이라고 생각하게 만든 사례로 소개됩니다.
진행자는 끝으로 실험용 모델 선택에 관한 조언을 남깁니다. 강화학습을 거친 모델은 조수 역할에 맞춰 출력의 다양성이 줄어드는 경향이 있으므로, 이름에 base가 붙은 강화학습 이전 모델이 이런 탐색에 더 좋은 실험 대상이라는 것입니다.
대회 참가자가 오늘 해 볼 수 있는 일
스티어링을 바로 제출 모델에 넣을 필요는 없습니다. 먼저 모델 내부를 들여다보는 도구로 써 보는 것이 안전합니다. 작은 오픈 모델을 쓰는 팀이라면 아래 순서로 한 시간 안에 첫 실험을 해 볼 수 있습니다.
- Qwen3 0.6B처럼 작은 모델을 불러와 원하는 층에 register_forward_hook을 걸고, 출력 활성값의 모양과 평균을 기록합니다.
- 대회 과제에서 구분하고 싶은 두 성질(예: 정답 형식을 지킨 답과 어긴 답)의 예문 묶음을 만들고, 층별 평균 차이 벡터를 구합니다.
- 강도를 0을 중심으로 음수와 양수로 바꿔 가며 같은 프롬프트의 출력을 나란히 비교합니다.
- 바꾸기 전 모델이 맞히던 기본 질문 묶음을 따로 두고, 설정을 바꿀 때마다 정답 수가 얼마나 줄었는지 같이 적습니다.
이 실험은 모델이 어느 층에서 과제와 관련된 차이를 만들기 시작하는지 알려 주므로, 미세조정할 층을 고르거나 프롬프트가 왜 듣지 않는지 추적할 때 근거가 됩니다. 진행 중인 AI 대회와 해커톤은 DAKER와 DACON에서 확인하실 수 있습니다. 직접 찾아본 층이나 뉴런이 있다면 이 게시판에 결과를 공유해 주십시오.
출처: Neural Breakdown with AVB 채널, 「Steering LLMs - Why neuron L23-N8799 turns Qwen absolutely evil (and how to find it)」(2026년 11월 1일 공개). 인용은 영상 음성을 번역한 것이며, 영상 속 수치는 진행자의 실험 결과입니다.