Qwen3.8-27B — Arabic Output Script Suppression
Qwen3.8-27B 가 아랍어로 답할 때 페르시아어 · 우르두어 정서법가 섞이는 것을 가중치 수준에서
줄이는 마스크입니다. lm_head 의 해당 토큰 행만 교체합니다.
측정 결과 (2026-09-01)
프롬프트 300건 짝지은 측정, B200 x1 · vLLM 0.28.0 · max_num_seqs=256 · 컴파일 켜짐.
마스크는 logit_bias -100 프록시로 걸었습니다(27B 에서 실가중치와 -0.03pp 재현).
⛔ 이 모델에서는 고칠 오염이 관측되지 않았습니다. base 오염률이 두 온도 모두 0.33% 로 바닥이고 마스크가 그것을 바꾸지 못했습니다. 마스크가 나쁘다는 뜻이 아니라 이 모델·이 프롬프트에서는 풀 문제가 없다는 뜻입니다. 다른 모델이나 페르시아어 인접 주제에서는 다를 수 있습니다.
| 온도 | base | 마스크 | 차이 | McNemar p | 판정 |
|---|---|---|---|---|---|
| 0.0 | 0.33% | 0.0% | -0.33pp | 1.0 | 측정력 없음 |
| 1.0 | 0.33% | 0.33% | 0.0pp | 1.0 | 측정력 없음 |
능력 회귀
| 축 | base | 마스크 | 차이 | 최소검출차 |
|---|---|---|---|---|
| coding | 94.51% | 94.51% | 0.0pp | 7.05pp |
| english | 80.5% | 80.5% | 0.0pp | 11.1pp |
⚠️ 차이가 최소검출차보다 작으면 '회귀 없음'이 아니라 '검출하지 못했다' 입니다.
대가 프로브 (생성 단위)
이 언어가 반드시 써야 하는 표현 6개를 요구하고 답에 살아 있는지 확인했습니다 — base 6/6 · 마스크 6/6, 마스크로 인한 손실 0건.
⚠️ 이 수치를 읽을 때
- 오염 문자 판정 기준이 마스크의 토큰 판정 기준과 같은 레퍼토리입니다. 독립적인 지표가 아닙니다.
- 프롬프트 300건 × 1회이고 반복 런이 없습니다 — 런간 산포는 재지 않았습니다.
- 능력 축(coding·english)은 마스크된 문자를 애초에 쓰지 않아 회귀 검출력이 구조적으로 약합니다. 그래서 대가 프로브를 따로 뒀습니다.
이 저장소에는 가중치가 없습니다
바뀌는 텐서가 lm_head.weight 하나뿐이라, 55.6GB 사본을 만드느니 원본을 받아 적용하는
편이 낫습니다.
hf download Qwen/Qwen3.8-27B --local-dir ./Qwen3.8-27B
python apply_mask.py --model-dir ./Qwen3.8-27B --mask mask_ar_t1.json
CPU 로 수 분, GPU 불필요합니다. 스크립트는 쓰기 전에 로짓 마진을 검증하고, 쓴 뒤 재로드해 의도 외 텐서가 안 바뀌었는지 assert 합니다.
마스크
규칙: 아랍 문자 블록에서 표준 아랍어 자모가 아닌 확장자(페르소-우르두)를 자른다.
| 파일 | 토큰 수 | 비고 |
|---|---|---|
mask_ar_t1.json |
815 | 기본값 |
mask_ar_t2.json |
825 | 더 공격적 |
mask_ar_t3.json |
66,520 | 더 공격적 |
토크나이저 프로브 (코드가 판정한 것)
측정은 못 했지만 마스크가 무엇을 자르고 무엇을 남기는지는 GPU 없이 확인할 수 있습니다. 기본 마스크 기준입니다.
- 보존 8/8 — مرحبا · كيف حالك · اللغة العربية · الْحَمْدُ · ١٢٣ · شكرا · ﷺ · ﷲ
- 억제 7/7 — پ · چ · ژ · گ · سلام خوبی · کتاب · ہے
build_masks_multi.py 를 돌리면 이 프로브가 그대로 재실행됩니다.
아랍어의 오염은 CJK 가 아니다
한국어 저장소의 마스크를 아랍어 문장에 대 보면 교집합이 정확히 0 이다. 스크립트가 겹치지 않으니 당연하고, 그래서 아랍어는 이식이 아니라 다른 실험이다.
아랍어 출력에서 실제로 새는 것은 같은 문자 블록을 공유하는 페르시아어·우르두어 정서법이다. 특히 눈에 안 띄는 두 쌍이 문제다.
| 표준 아랍어 | 페르소-우르두 | 겉보기 |
|---|---|---|
| ي (U+064A, YEH) | ی (U+06CC, FARSI YEH) | 거의 동일 |
| ك (U+0643, KAF) | ک (U+06A9, KEHEH) | 거의 동일 |
여기에 아랍어에 없는 자음 پ چ ژ گ 와 우르두 전용 ٹ ڈ ڑ ں ھ ے 가 더해진다. 눈으로는 잘 안 보이는데 검색·정규화·TTS 는 전부 깨진다.
판정 기준과 ⛔ 예외 처리
iso8859-6(표준 아랍어 인코딩) 가능 여부를 1차 기준으로 쓰되, 그것만으로는 안 된다.
정당한데 iso8859-6 밖인 것들이 있어서 명시적으로 보존한다.
- 아랍-인도 숫자
٠١٢٣٤٥٦٧٨٩(U+0660–0669) - 타슈킬(모음부호)
َ ِ ُ ّ ْ(U+064B–065F) —الْحَمْدُ같은 정자 표기 - 꾸란 주석 기호 (U+06D6–06ED), superscript alef (U+0670)
⚠️ t2 는 기본값이 아니다 — 경칭 리가처를 깬다
t2 는 아랍어 표현형(U+FB50–FDFF, U+FE70–FEFF)까지 자르는데, 그 안에 ﷺ(U+FDFA)와
ﷲ(U+FDF2) 가 들어 있다. 둘 다 아랍어 본문에서 정상적으로 쓰이는 경칭이다. 실제로 이
프로젝트의 프로브가 처음에 ﷺ 를 오염원으로 잘못 분류했다가 잡혔다. 레거시 리가처를
정규 자모로 통일하려는 목적이 명확할 때만 t2 를 쓴다.
방법
lm_head.weight 의 대상 행을 은닉상태 평균 방향의 큰 음수 배수로 대체합니다.
W_i := -alpha * mu_h / ||mu_h||^2 (alpha = 200)
lm_head 에 bias 가 없어 행을 0 으로 만들면 로짓이 0 이 될 뿐 −inf 가 아닙니다. 다른
후보가 전부 음수인 순간 0 이 argmax 가 됩니다. mu_h 는 forward pass 로 측정합니다.
⚠️ apply_mask.py 의 PROBE_TEXTS 는 한국어 문장입니다. 이 언어를 타깃으로 쓴다면
해당 언어 문장으로 바꾸는 편이 맞습니다 — mu_h 는 "이 모델이 그 언어를 쓸 때의 평균
은닉상태" 여야 의미가 있습니다. 바꾸면 ||mu_h||² 도 달라지니 스크립트가 출력하는
마진 검증을 반드시 확인하세요.
한계
- ⚠️
temperature를 낮게 쓰세요. 한국어 실측에서 온도가 오염률을 5배 좌우했습니다 (T=1.09.33% vsT=0.01.92%). - 가지치기의 하한은 0 이 아닙니다. 희귀 글자는 어휘에 단독 토큰이 없어 바이트 조각으로 조립되고, 그 바이트 토큰은 자를 수 없습니다.
- 영어 혼입은 이 기법으로 못 고칩니다. 영어 토큰은 코드·고유명사·단위 때문에 살려야 하므로 잘라낼 수 없는 오염원입니다.
- 이것은 위생 처리이지 문체 개선이 아닙니다.
선행 연구
dnotitia/smoothie-qwen 이 같은 방향(Qwen
lm_head 조정으로 중국어 억제)으로 사전조정본을 배포하고 있습니다. 이 저장소가 더한 것은
타깃 언어별 레퍼토리 판정(간체/번체 축이 아니라 legacy 국가 인코딩)과 언어마다 다른
티어 구조입니다.
관련: SASFT (ICLR 2026) · Korean token pruning · TLPO (ACL 2026)
라이선스
apache-2.0 — 베이스 Qwen/Qwen3.8-27B 와 동일. 마스크·스크립트만 배포하며 가중치를
재배포하지 않습니다.
Model tree for ThakiCloud/Qwen3.8-27B-ar-script-suppressed
Base model
Qwen/Qwen3.8-27B