회사 테크

Uncensored Qwen3.8 Flash Next, Terminal-Bench 89개 완주 기록

커뮤니티 abliterated 파생 모델로 Terminal-Bench 2.1 89개를 사흘간 완주했습니다. 컨텍스트·타임아웃·온도를 네 번 바꾼 과정과 wedge 13회, 최종 56/89 점수의 의미를 정리합니다.

삽질하는개발자

노트와 노트북이 놓인 상담 책상

지난 글은 70개까지 돌린 중간 보고였습니다. 이번 글은 89개를 다 돌리고, 실패한 태스크를 조건을 바꿔 두 번 더 돌린 최종 기록입니다. 08-31 밤에 시작해 09-03 저녁에 끝났습니다.

먼저 밝혀둘 게 하나 있습니다. 지난 글에서 빠뜨린 부분입니다.

이 모델은 공식 Qwen이 아닙니다

테스트한 모델은 ARC4NUM/Qwen3.8-Flash-Next-Uncensored-MLX-Serve-4bit입니다. 이름에 있는 Uncensored가 핵심입니다. Qwen 팀이 배포한 Flash Next에서 거절 응답 방향을 지운 abliterated 파생본을, 커뮤니티 사용자가 mlx-serve용 4bit로 다시 양자화한 것입니다. Qwen 공식 배포본이 아닙니다.

abliteration은 모델 내부에서 거절과 관련된 방향 벡터를 찾아 제거하는 방식입니다. 원래 가중치를 건드리기 때문에 능력이 얼마나 손상됐는지는 배포자도 정확히 모릅니다. 그러니 이 글의 점수는 원본 Flash Next의 점수가 아닙니다. 4bit 양자화 손실과 abliteration 손실이 섞여 있고, 이 글의 실험만으로는 둘을 분리할 수 없습니다.

왜 이걸 골랐냐면, 실험 시작 시점에 mlx-serve에서 MTP까지 바로 동작하는 Flash Next 4bit이 이것뿐이었기 때문입니다. 연구 목적으로만 썼고, 결론에서 다시 한 번 짚겠습니다.

테스트 환경

항목
모델 Qwen3.8-Flash-Next-Uncensored-MLX-Serve-4bit (125B 전체 / 6B 활성, 48층, 512 전문가)
서버 mlx-serve 26.8.11, --mtp --kv-quant 8 --prefill-chunk 8192 --max-concurrent 2
상주 메모리 70.13 GB
하네스 Harbor Terminal-Bench 2.1, terminus-2 에이전트, 태스크당 시도 1회
컨테이너 Colima (--vz-rosetta)
채점 verifier_result.rewards.reward > 0이면 PASS

타임아웃은 태스크마다 기본값이 다릅니다. 900초짜리(raman-fitting, qemu-startup, tune-mjcf 등)부터 3600초짜리(regex-chess, train-fasttext, video-processing 등)까지 있고, 나머지는 1800초입니다. 여기에 --agent-timeout-multiplier를 곱합니다. 아래에서 0.5×, 1.0×라고 쓰는 게 이 배수입니다.

전체 타임라인

사흘 동안 조건을 네 번 바꿨습니다. 한 표로 먼저 보여드리고 단계별로 풀겠습니다.

단계 기간 서버 ctx max_input reasoning / temp 타임아웃 결과
파일럿 08-31 낮 131072 110000 medium / 0.7 3.0× 5/5
밤샘 (배치 1~6) 08-31 22:35 → 09-01 05:46 131072 → 65536 110000 → 55000 medium / 0.7 1.0× 13/22
본실행 (배치 7~16) 09-01 20:08 → 09-02 09:00 65536 55000 medium / 0.7 1.0× 23/48
잔여 19개 09-02 10:36 → 15:21 65536 55000 medium / 0.7 0.5× 5/19
재실행 1 (실패 48개) 09-02 15:25 → 09-03 01:59 131072 120000 high / 0.3 0.5× 9/48
재실행 2 (실패 39개) 09-03 02:02 → 18:36 131072 120000 high / 0.3 1.0× 6/39

단일 실행 기준 점수는 41/89, 46.1%입니다. 재실행 두 번에서 건진 15개를 더한 best-of 점수는 56/89, 62.9%입니다. 두 숫자는 의미가 다르니 결론에서 따로 다룹니다.

1단계: 밤샘 실행, 컨텍스트를 절반으로 줄이다

첫날 밤은 지난 글에서 다뤘으니 설정 변경만 짚습니다.

서버는 --ctx-size 131072, 하네스 max_input_tokens는 110000으로 시작했습니다. 22:03과 01:35에 서버가 두 번 멈췄습니다. state: ready인데 14토큰짜리 요청도 처리를 못 하고, RSS가 70 GB에서 3.5 GB로 무너지는 증상입니다. 두 번 다 hot-cache가 15 GB에 도달한 직후 새 태스크의 첫 프리필에서 났습니다. 이 증상을 이 글에서는 wedge라고 부릅니다.

캐시 엔트리 하나의 크기가 컨텍스트 길이에 비례하므로, 01:35 복구 때 --ctx-size를 65536으로 줄였습니다. 이후 4시간은 wedge가 없었습니다.

그런데 서버만 줄이고 하네스 상한을 110000으로 놔둔 게 새 문제를 만들었습니다. terminus-2는 max_input_tokens를 믿고 “남은 토큰 53104”라고 계산한 뒤 요청을 보내고, 서버는 65536 초과라며 거부합니다. 에이전트는 대화를 요약하고 다시 보내고, 또 거부당합니다. dna-assembly에서 이 순환이 55회 돌았고, 04:42에 배치 5를 통째로 취소했습니다. 배치 5의 다섯 태스크는 뒤에 “잔여 19개”로 다시 돌렸습니다.

max_input_tokens를 55000으로 낮추자 배치 6은 fallback 0건으로 깨끗했습니다. 교훈은 하나입니다. 서버 ctx-size를 바꾸면 하네스 model_info도 같이 바꿔야 합니다.

2단계: 본실행, wedge는 계속 났다

09-01 20:05에 재개하려다 첫 시도는 1분 만에 배치 7부터 13까지 전부 “종료”로 찍혔습니다. Colima가 내려가 있어서 Docker daemon이 없다는 오류였습니다. 올리고 20:08에 다시 시작했습니다.

이번엔 2분마다 ping을 보내 두 번 연속 실패하면 서버를 재시작하는 watchdog를 붙였습니다. 09-02 01:24, 03:12, 08:14, 08:36 네 번 wedge를 잡아 재시작했습니다. ctx를 65536으로 줄여도 wedge가 사라지지 않았다는 뜻입니다. 15 GB 캐시 조건은 피했지만, 5만 토큰 안팎 큰 요청 직후 다음 요청이 멈추는 패턴은 그대로였습니다.

배치 7~16의 48개 중 23개를 통과했습니다. 밤샘분과 합쳐 70개 중 36개, 51.4%가 지난 글의 숫자입니다. 다만 이 70개 중 3개는 모델 탓이 아닌 실패였습니다. nginx-request-logging과 model-extraction-relu-logits는 docker compose가 환경을 못 올려 RuntimeError로 끝났고, sanitize-git-repo는 마감 시각에 CancelledError로 잘렸습니다.

3단계: 잔여 19개는 타임아웃 절반으로

wedge로 날아간 배치 2의 3개, 취소한 배치 5의 5개, 그리고 배치 16 이후 순서가 오지 않은 11개를 합쳐 19개가 남았습니다. 시간을 아끼려고 타임아웃을 0.5×로 낮춰 09-02 10:36부터 15:21까지 돌렸습니다. 5개 통과, 10개 타임아웃, 4개 실패였습니다.

여기서 단일 실행 89개가 완성됐습니다. 41/89, 46.1%. 지난 글의 51.4%보다 낮아진 이유는 뒤쪽 19개가 어려운 태스크에 몰려 있었고 시간도 절반이었기 때문입니다. 실패 48개의 내역은 타임아웃 29개, 시간 안에 끝냈지만 틀린 것 16개, 인프라 오류 3개입니다.

4단계: 실패 48개를 조건 바꿔 재실행

절반 넘게 타임아웃이라, 하네스 조건이 발목을 잡은 건지 모델 한계인지 가리고 싶었습니다. 실패 48개만 골라 세 가지를 바꿨습니다.

  • 서버 ctx를 131072로 되돌리고 max_input_tokens를 120000으로 올렸습니다. 요약 없이 긴 대화를 유지하게 하려는 것입니다.
  • reasoning_effort를 medium에서 high로, temperature를 0.7에서 0.3으로 바꿨습니다.
  • 타임아웃은 0.5×로 뒀습니다. 48개를 밤 안에 끝내려는 타협이었습니다.

09-02 15:25부터 09-03 01:59까지 돌아 9개가 통과로 뒤집혔습니다.

태스크 재실행 소요 최대 ctx 본실행 결과
adaptive-rejection-sampler 6.5분 23K 타임아웃 15.0분
build-pov-ray 10.6분 19K 실패
crack-7z-hash 10.3분 10K 타임아웃 30.0분
feal-differential-cryptanalysis 15.0분 (타임아웃이지만 채점 통과) 65K 타임아웃 15.0분
nginx-request-logging 1.2분 3K docker compose 오류
polyglot-rust-c 7.5분 (타임아웃이지만 채점 통과) 27K 타임아웃 15.0분
pytorch-model-recovery 3.4분 12K 실패 7.1분
regex-log 6.4분 33K 실패 3.0분
reshard-c4-data 13.9분 26K 실패 20.0분

타임아웃이지만 채점 통과라는 게 가능합니다. Harbor는 에이전트가 시간에 걸려도 그 시점의 컨테이너 상태를 채점합니다. 파일이 이미 맞게 만들어져 있으면 PASS입니다.

nginx-request-logging은 본실행이 인프라 오류였으니 진짜 뒤집힌 건 8개입니다. 온도를 낮추고 reasoning을 올린 효과인지, 단순히 한 번 더 돌린 운인지는 이 실험으로는 구분이 안 됩니다. 시도 1회씩이라 분산을 재지 못했습니다.

이 재실행 중에도 wedge는 세 번 났습니다. 20:55, 21:02, 23:23. 20:55와 21:02는 7분 간격입니다. 재시작 직후 같은 큰 요청이 다시 들어와 곧바로 다시 멈춘 것입니다.

5단계: 남은 39개를 타임아웃 원래대로

재실행 1에서 여전히 실패한 39개에 같은 조건으로 타임아웃만 1.0×로 올려 돌렸습니다. 09-03 02:02부터 18:36까지, 16시간 반이 걸렸습니다. 6개가 뒤집혔습니다.

태스크 소요 최대 ctx 비고
build-cython-ext 15.0분 37K 본실행·재실행 1 모두 타임아웃, 제한 900초를 꽉 채워 통과
code-from-image 4.6분 12K
count-dataset-tokens 8.0분 12K
model-extraction-relu-logits 3.0분 14K 본실행은 docker compose 오류
password-recovery 5.2분 25K
winning-avg-corewars 60.0분 70K 타임아웃이지만 채점 통과

나머지 33개의 전이는 이렇습니다.

  • 타임아웃 → 타임아웃 23개. 이 중 8개는 컨텍스트가 100K를 넘겼습니다. path-tracing-reverse 130K, mteb-leaderboard 126K, make-mips-interpreter 123K, regex-chess 122K, schemelike-metacircular-eval 118K, circuit-fibsqrt 116K, dna-assembly 109K, custom-memory-heap-crash 95K.
  • 타임아웃 → 실패 3개. compile-compcert 26.8분, install-windows-3.11 41.2분, sanitize-git-repo 3.4분. 시간을 두 배 줘도 끝내고 틀렸습니다.
  • 실패 → 실패 5개. dna-insert, extract-elf, query-optimize, sparql-university, train-fasttext(41.7분).
  • 실패 → 타임아웃 2개. protein-assembly, video-processing(130K).

이 단계에서 wedge는 네 번 났습니다. 07:43, 10:45, 13:13, 14:21.

131K 컨텍스트가 만든 새 실패

ctx를 131072로 되돌리자 wedge와 다른 종류의 문제가 나타났습니다. 09-02 01:24 이후 서버 로그에 prompt N tokens exceeds ctx_size 131072 400 응답이 5,266건 찍혔습니다. 거의 전부가 재실행 두 번에서 나온 것입니다.

에이전트가 120K 근처까지 대화를 채우면 다음 요청이 131072를 넘깁니다. terminus-2는 요약을 시도하는데, 요약 요청 자체도 컨텍스트를 넘겨 실패합니다. 로그에는 Even fallback chat failed가 반복됩니다. 재실행 2 로그에서 이 줄이 1,386번 나왔습니다. 그 뒤로는 타임아웃까지 아무 일도 하지 못합니다.

video-processing은 더 이상한 모습이었습니다. 컨텍스트가 92K를 넘긴 시점부터 112K까지, 매 턴 620토큰짜리 똑같은 출력을 반복했습니다. 명령을 바꾸지도 않고 같은 걸 계속 냈습니다. 그러다 131K를 넘겨 400을 받고 끝났습니다. 100K를 넘긴 8개 태스크가 하나도 안 뒤집힌 데는 이런 긴 컨텍스트 열화가 깔려 있습니다.

wedge 13회, 가짜 알람 16회

사흘 통틀어 서버가 멈춘 건 13번입니다. 첫날 밤 수동 복구 2번, watchdog 자동 복구 11번. 시각을 다 적어두면 이렇습니다.

날짜 시각 복구 당시 ctx
08-31 22:03 수동 131072
09-01 01:35 수동, ctx 65536으로 축소 131072
09-02 01:24 / 03:12 / 08:14 / 08:36 watchdog 65536
09-02 20:55 / 21:02 / 23:23 watchdog 131072
09-03 07:43 / 10:45 / 13:13 / 14:21 watchdog 131072

패턴은 두 가지였습니다. 하나는 60K 넘는 컨텍스트에서 긴 출력을 낸 직후 다음 요청이 멈추는 것. 다른 하나는 메모리 압박입니다. RSS가 50 GB 근처로 내려가고 free 메모리가 0.4 GB 이하로 떨어진 상태에서 났습니다.

watchdog는 ping이 한 번 실패하고 다음에 살아난 경우도 16번 기록했습니다. 서버가 큰 프리필을 처리하느라 45초 안에 4토큰을 못 돌려준 경우입니다. 두 번 연속 조건이 없었다면 멀쩡한 서버를 16번 더 죽였을 겁니다.

메모리 얘기를 하나 더 하면, 실험 시작 때 17.4 GB이던 swap이 사흘 뒤 29.7 GB까지 올라갔습니다. 중간에 제 실수로 같은 머신의 다른 추론 서버가 20 GB 모델을 올려버린 사고가 있었습니다. free 메모리가 1.0 GB까지 떨어지고 mlx-serve RSS가 1.4 GB로 페이지아웃됐지만, 7분 안에 정리해서 서버는 끊기지 않았습니다. 70 GB 모델 옆에 다른 걸 올릴 여유가 없다는 걸 몸으로 배웠습니다.

숫자를 어떻게 읽을까

단일 실행 41/89(46.1%)와 best-of 56/89(62.9%) 중 어느 게 이 모델의 점수냐고 물으면, 둘 다 조건이 붙는 숫자입니다.

단일 실행 41개는 조건이 균일하지 않습니다. 70개는 1.0×, 19개는 0.5×였고, 3개는 인프라 오류였습니다. best-of 56개는 시도 3회 중 한 번이라도 통과한 수라 공식 리더보드와 비교하면 안 됩니다. 정직하게 말하면 “이 모델은 이 하네스에서 46%쯤 나오고, 시간과 설정을 더 주면 63%까지는 닿는다” 정도입니다.

실패 48개 중 15개(31%)가 재실행에서 뒤집혔고, 뒤집힌 태스크의 최대 컨텍스트는 전부 70K 이하였습니다. 반대로 시간 안에 끝내고 틀린 태스크는 시간을 두 배 줘도 한 번도 안 뒤집혔습니다. 컨텍스트가 100K를 넘긴 태스크도 한 번도 안 뒤집혔습니다. 그러니까 시간·설정으로 건질 수 있는 몫은 짧은 태스크의 타임아웃이고, 나머지는 모델 쪽 한계로 보는 게 맞습니다.

그 한계가 4bit 양자화 때문인지 abliteration 때문인지가 남은 질문입니다. 앞에서 말했듯 이 모델은 Uncensored 파생본이라 원본 Flash Next의 점수로 읽으면 안 됩니다. 같은 하네스로 abliteration이 없는 ddalcu/Qwen3.8-Flash-Next-MLX-Serve-mixed-4-8bit(전문가 4bit, 어텐션 8bit, MTP 유지)를 돌릴 준비를 하고 있습니다. 107 GB를 받는 중이고, 재실행 2와 같은 조건으로 89개를 돌리면 35~40시간이 걸립니다. 그 결과가 나와야 두 손실을 갈라 볼 수 있습니다.

다음에 다시 한다면

  • 서버 ctx와 하네스 max_input은 한 쌍입니다. 하나만 바꾸면 요약 무한 루프가 납니다.
  • ctx를 줄여도 wedge는 안 사라집니다. watchdog는 처음부터 붙이고, 두 번 연속 실패 조건은 꼭 둡니다.
  • 타임아웃을 절반으로 줄이면 짧은 태스크 위주로 점수가 깎입니다. 시간이 없으면 태스크 수를 줄이는 게 낫습니다.
  • 120K 컨텍스트를 열어주는 건 이 모델에게 이득이 없었습니다. 100K 넘게 채운 태스크는 전부 실패했습니다.
  • 시도 1회는 분산을 못 잽니다. 뒤집힌 8개가 설정 덕인지 운인지 모릅니다.