이 글 공유하기

핵심 요약

Qwen3.8-27B를 Verilog RTL 생성에 맞춰 학습한 Thaki-HW-27B-v0.1을 Hugging Face에 공개했습니다. 결과부터 적습니다. 학습 전에 정해 둔 공개 기준은 통과했지만, 원본 Qwen3.8-27B보다 낫다는 통계적 증거는 나오지 않았습니다. VerilogEval은 +0.85%p였고 95% 신뢰구간이 0을 포함합니다. RTLLM은 −4.27%p로 점추정이 오히려 낮고, 하락 가능성을 배제하지 못했습니다.

그래서 이 모델은 research preview입니다. 실무에는 원본 모델을 권합니다. 그런데도 이 글을 쓰는 이유는 실패의 모양이 꽤 구체적이기 때문입니다. 156개 과제 중 103개는 결과가 그대로였고, 28개는 좋아졌고, 25개는 나빠졌습니다. 좋아진 쪽은 플립플롭·카운터·시프트 레지스터 같은 단순한 순차 회로였고, 나빠진 쪽은 상태가 많은 FSM과 RTLLM의 산술 회로였습니다. 이 글은 데이터를 어떻게 만들었는지, 평가 기준을 어떻게 미리 묶었는지, 그리고 이 결과에서 무엇을 배웠는지를 정리합니다.

왜 만들었고, 그전에 무엇이 실패했나

RTL 생성은 코드 생성 중에서도 정답 확인이 엄격한 분야입니다. 문법이 맞아 합성이 되더라도 테스트벤치에서 한 사이클만 어긋나면 틀린 회로입니다. 범용 코딩 모델이 Verilog를 어느 정도 쓰기는 하지만, 사내 하드웨어 설계 에이전트를 만들려면 이 정확도를 끌어올릴 방법이 필요했습니다.

v0.1 전에 두 번 시도했고 두 번 다 실패했습니다. 평가 조건이 이번과 달라서 수치를 그대로 비교할 수는 없지만, 실패 패턴은 분명했습니다.

  • Gate 0: 공개 RTL 약 9,500행으로 LoRA를 학습했습니다. update 총량(학습률 × 스텝 수)이 0.191이었고, RTLLM이 24.8%p 떨어졌습니다.
  • P2-R0: 342행을 2 epoch 학습했습니다. 최종 loss가 0.0005까지 내려가 사실상 암기였습니다. VerilogEval 기능 정답률은 5.51%p 떨어졌는데 컴파일률은 4.10%p 올랐습니다.

두 번째 패턴이 특히 중요했습니다. 모델이 “컴파일되는 Verilog를 쓰는 법”은 배웠지만 “맞는 회로를 쓰는 법”은 잃었습니다. 컴파일률만 보면 개선처럼 보이는 결과였습니다. v0.1은 이 두 실패를 반복하지 않는 것을 첫 목표로 설계했습니다.

데이터: 라이선스가 추적되는 시드와 자기증류

시드를 7,257개까지 줄인 이유

학습 데이터의 출발점은 OpenRTLSet의 131,309개 Verilog 모듈입니다. 공개 모델에 넣을 데이터라서 거르는 기준을 보수적으로 잡았습니다.

단계 남은 모듈
OpenRTLSet 전체 131,309
행마다 원본 저장소 라이선스가 허용(MIT·Apache·BSD 등)이고 기계 생성 저장소가 아님 57,610
같은 코드가 비허용 라이선스 행에 한 번이라도 나오면 제외 39,665
Verilator lint 통과, 단일 모듈, 입출력 포트만 사용 23,596
길이 조건 20,865
평가 벤치마크와의 오염 제거 20,460
중복 제거 14,031
사내 봉인 벤치마크 계열 제외 7,257

여기에 모듈 설명이 붙은 데이터셋과 코드가 정확히 일치하는 시드만 남기니 3,545개였습니다. 이 설명은 원본 RTL을 보고 LLM이 역으로 쓴 글이라 독립적인 사양서가 아닙니다. 설명에 코드가 새어 들어가지 않도록 코드형 줄 수와 원본 코드와의 6-gram 겹침에 상한을 두었습니다.

원본 코드를 정답으로 쓰지 않은 이유

이 시드의 원본 RTL을 그대로 학습 정답으로 쓰지 않았습니다. 대신 Qwen3.8-27B에게 설명과 포트 정의만 주고 RTL을 직접 쓰게 했고, 그 결과물이 원본과 Yosys 형식 동치 검사를 통과할 때만 학습에 넣었습니다. 순차 회로는 초기 상태 0에서 50 사이클까지, 조합 회로는 SAT로 확인했습니다. 시드 하나에서는 하나만 채택해 쉬운 과제에 데이터가 몰리지 않게 했습니다.

이렇게 한 데는 두 가지 이유가 있습니다. 하나는 정답 확인입니다. 사람이 쓴 원본 코드라도 그 설명과 정확히 대응한다는 보장이 없는데, 동치 검사를 통과한 생성물은 최소한 원본과 같은 동작을 합니다. 다른 하나는 공개 권리입니다. 공개 근거는 원본 RTL의 라이선스에서 가져오고, “모델 출력이니 자유롭게 써도 된다”는 논리에 기대지 않았습니다.

16,576건을 생성했고 최종 채택은 1,452건이었습니다. 이 가운데 1,000건을 회로 계열별로 고르게 뽑되, 계열 안에서는 복잡한 것부터 골랐습니다. 여기에 일반 코딩 replay 317행(OpenCodeInstruct, CommitPackFT 허용 라이선스 부분)을 섞었습니다.

판정기가 데이터를 깎은 방식

파일럿 400개 시드에서 생성 1,600건 중 PASS는 537건(33.6%)이었습니다. 판정 불능(ERROR) 321건 중 약 61%는 모델 잘못이 아니라 판정기 한계였습니다. Yosys SAT는 메모리 셀과 비동기 플립플롭·래치를 모델링하지 못합니다. 그래서 FIFO와 메모리 계열은 회로를 맞게 써도 채택될 수 없었습니다. 최종 1,000행 중 FIFO는 5행, accelerator datapath는 10행에 그쳤습니다. 이 편향은 학습 전에 알았고 카드에도 적었습니다.

학습: 이전 실패보다 작게 움직이기

레시피는 한 가지로 고정하고 grid를 돌리지 않았습니다.

항목 값
베이스 Qwen3.8-27B (revision 1d4bf0f2, 학습 전 safetensors 18개 sha256 대조)
방법 LoRA r=8, alpha=16, 언어 모델 선형층 496개(linear attention 포함, 비전 인코더 제외)
학습률 5e-5 고정, warmup 없음
데이터 HW 1,000행 + 코딩 replay 317행, 1 epoch, 1,317 step
update 총량 5e-5 × 1,317 ≈ 0.066 (Gate 0의 0.191보다 작게)
형식 비사고 모드 대화. 추론 trace는 학습하지 않음
GPU B200 1장, 트랙 전체(생성·학습·병합·평가) 4.6 GPU-h

update 총량을 Gate 0의 약 3분의 1로 묶은 것이 핵심 결정이었습니다. P2-R0는 총량 0.068에서도 망가졌지만, 그건 342행을 두 번 돌린 암기였습니다. 이번에는 비슷한 총량을 고유한 1,000행 1 epoch와 replay 위에 나눠 실었습니다.

학습 뒤에는 LoRA를 bf16 원본 가중치에 fp32로 병합했습니다. 병합 전후 출력 차이(logit 최대 차이 1e-2 이하), 대상이 아닌 텐서의 비트 일치, 서빙 결정론, HF 업로드본과 S3 원본의 파일별 해시 일치를 코드로 확인했습니다.

평가: 결과를 보기 전에 기준을 고정했다

평가 조건과 공개 기준은 GPU에 잡을 넣기 전에 문서로 고정하고 그 해시를 남겼습니다. 결과를 보고 기준을 고치지 않기 위해서입니다.

  • 조건: thinking 모드, 최대 출력 65,536 토큰, vLLM 0.29 bf16, 모델 카드 권장 샘플링(T 1.0, top_p 0.95, top_k 20). 원본과 학습본에 같은 이미지와 같은 서빙 플래그를 썼습니다.
  • 벤치마크: VerilogEval v2 spec-to-RTL 156과제, RTLLM 중 빈 응답으로 통과되지 않는 39과제(둘 다 과제당 3샘플), HumanEval+MBPP 661문항(1샘플).
  • 통계: 과제 단위 paired bootstrap(B=10,000), 95% 신뢰구간.
  • 공개 기준: VerilogEval 2.0%p 넘게 하락하면 실패, RTLLM은 과제 2개분(5.13%p) 넘게 하락하면 실패, 코딩은 3.0%p 넘게 하락하면 실패. 컴파일률이 오르는데 기능 정답률이 그대로이거나 떨어지면 “개선”이라고 부르지 못하게 하는 규칙도 따로 두었습니다. P2-R0 패턴을 잡기 위한 규칙입니다.

과제 하나의 무게도 미리 계산했습니다. VerilogEval은 과제 하나가 0.64%p, RTLLM은 2.56%p입니다. RTLLM에서 4%p는 과제 두 개가 채 안 되는 차이라는 뜻입니다.

결과: 공개 기준은 통과했고, 개선은 입증하지 못했다

벤치마크 Qwen3.8-27B Thaki-HW-27B-v0.1 Δ 95% CI
VerilogEval v2 (156) 119.67 (76.7%) 121.00 (77.6%) +0.85%p [−2.99, +4.70]
RTLLM (39) 31.67 (81.2%) 30.00 (76.9%) −4.27%p [−12.82, +4.27]
HumanEval+MBPP (661) 649 (98.2%) 649 (98.2%) 0.00%p [−1.06, +1.06]

정답 수는 과제별 3샘플 평균 통과율을 더한 값입니다. 세 벤치마크 모두 공개 기준 안에 들었지만, 세 신뢰구간이 모두 0을 포함합니다. 사전에 정한 분류대로 쓰면 “공개 기준 통과·개선 미입증”입니다. 코딩은 원본이 이미 98.2%라 천장에 가깝습니다. 이 벤치마크로는 하락만 볼 수 있고 개선은 볼 수 없습니다.

컴파일률은 VerilogEval이 +2.14%p, RTLLM이 −8.55%p였습니다. VerilogEval에서는 기능 정답률도 같이 올라 P2-R0 패턴(컴파일↑ 기능↓) 규칙에 걸리지 않았습니다. RTLLM은 둘 다 내려갔습니다.

출력 길이는 줄었습니다. thinking을 포함한 평균 생성 토큰이 VerilogEval에서 6,703에서 5,720으로, RTLLM에서 15,966에서 14,121로 내려갔습니다. 비사고 모드 답만 학습했는데도 사고 모드 출력이 짧아졌습니다. 서빙 비용에는 유리한 변화지만, 이것이 정답률 변화와 어떻게 연결되는지는 따로 측정하지 않았습니다.

어디서 좋아지고 어디서 나빠졌나

평균은 거의 그대로였지만, 과제별로는 양쪽으로 크게 움직였습니다. 과제당 샘플이 3개뿐이라 0.33 변화는 샘플 하나 차이입니다. 아래 내용은 통계적 결론이 아니라 패턴 관찰로 읽어야 합니다.

VerilogEval: 28개 상승, 25개 하락, 103개 동일

  • 좋아진 과제: count10, dff8r, dff8ar, shift4, edgecapture, rotate100, dff16e, lfsr32, fsm1s, fsm3s, fsm_onehot 등. 플립플롭, 카운터, 시프트 레지스터, 상태가 적은 FSM이 대부분입니다. 33%에서 100%로 오른 과제가 6개 있었습니다.
  • 나빠진 과제: lemmings1~lemmings4, review2015_fancytimer, review2015_fsmseq, fsm_ps2data, gshare, rule110, count_clock, always_casez 등. 상태가 여럿이고 전이 조건이 긴 행동형 FSM, 분기 예측기 같은 구조가 눈에 띕니다. Lemmings 문제 네 개가 모두 떨어진 것은 우연으로 넘기기 어려운 패턴입니다.
  • 둘 다 한 번도 못 푼 과제는 13개였습니다. 학습이 이 과제들을 하나도 열지 못했습니다.

RTLLM: 6개 상승, 9개 하락, 24개 동일

  • 좋아진 과제: ROM, LIFObuffer, parallel2serial, freq_div, multi_16bit, fixed_point_substractor.
  • 나빠진 과제: multi_8bit, sub_64bit, adder_32bit, alu, div_16bit, float_multi, fsm, JC_counter, traffic_light. 산술 회로가 여럿 떨어졌습니다.

이 결과는 학습 데이터의 성격과 들어맞습니다. 학습 정답은 원본 모델이 이미 맞힌 답 중 동치 검사를 통과한 것이었습니다. 그렇게 모은 데이터에는 판정기가 잘 다루는 짧은 순차 회로가 많고, 원본이 잘 못 푸는 복잡한 회로는 적습니다. 결과적으로 원래 잘하던 쪽은 더 안정되었고, 데이터가 거의 없던 쪽은 흔들렸습니다. 사전등록 문서에 “가장 강한 반론”으로 적어 둔 바로 그 시나리오였습니다. 자기증류는 이미 하는 것을 날카롭게 할 뿐, 없는 능력을 더해 주지 않는다는 반론입니다.

같은 조건의 대조 트랙: 참조 RTL로 학습한 경우

같은 레시피로 비교용 트랙을 하나 더 돌렸습니다. 이 트랙은 모델이 생성한 코드 대신 공개 데이터셋의 참조 RTL을 정답으로 썼습니다(출처 계보를 확인하지 못한 행이 섞여 있어 내부 비교용으로만 쓰고 공개하지 않습니다). 스텝 수, replay 집합, update 총량은 공개 트랙과 같게 맞췄습니다.

벤치마크 공개 트랙(자기증류) 대조 트랙(참조 RTL)
VerilogEval +0.85%p [−2.99, +4.70] −1.92%p [−5.98, +1.92]
RTLLM −4.27%p [−12.82, +4.27] −5.13%p [−12.82, +1.71]
코딩 0.00%p [−1.06, +1.06] −1.51%p [−3.03, −0.15]

대조 트랙은 코딩에서 하락이 통계적으로 검출됐고, VerilogEval에서 컴파일률이 오르며 기능 정답률이 떨어지는 패턴도 나왔습니다. 사람이 쓴 참조 코드로 학습한 쪽이 더 나빴다는 뜻입니다. 다만 두 트랙은 정답의 작성자뿐 아니라 데이터 출처와 학습 토큰 수(679K 대 826K)도 다릅니다. 그래서 이 차이를 “자기증류가 낫다”는 결론으로 읽지는 않습니다.

공개 뒤에 찾은 것: 학습 데이터 감사

공개 뒤에 학습 데이터 1,000행을 다른 방법으로 다시 검사했습니다. 형식 동치 대신 iverilog 차분 시뮬레이션으로 원본과 생성 코드를 비교했습니다. 729행은 일치했고, 27행에서 출력 차이가 나왔고, 244행은 판정하지 못했습니다. 차이 일부는 시뮬레이션 환경 차이일 수 있어서 학습 데이터의 실제 오류율은 확정하지 못했습니다. 이 27행은 이미 학습에 쓰였고, 재학습은 하지 않았습니다. 감사 결과는 모델 카드에 추가했습니다.

형식 동치 검사는 “초기 상태 0에서 50 사이클까지 원본과 같다”는 제한된 보장입니다. 사양을 기준으로 한 정답 증명이 아닙니다. 이 감사는 그 한계가 실제 데이터에서 어떻게 드러나는지 보여 줍니다.

확대판을 학습하지 않은 이유

데이터를 3,000~5,000건으로 늘린 확대판(v0.1-L)도 미리 계획해 두었습니다. 주 지표는 전체 행 수가 아니라 부족한 계열의 증가량이었습니다. 목표는 FIFO 15개, accelerator datapath 25개, memory 250개 이상이었습니다. 판정기를 보강하고 다시 셌는데, 신뢰할 수 있는 판정 경로를 통과한 것은 FIFO 2개, accelerator 0개, memory 0개였습니다. 목표 미달이 확정되어 학습하지 않고 닫았습니다.

자기증류와 참조 동치 검사 조합으로는 원본이 못 푸는 계열의 데이터를 만들 수 없었습니다. v0.1의 실패와 확대판의 종료가 같은 사실을 가리킵니다.

배운 것

  1. 컴파일률은 지표가 아니라 함정이 될 수 있습니다. P2-R0에서 컴파일률이 오르고 기능 정답률이 떨어지는 것을 본 뒤, 이 패턴을 게이트 규칙으로 고정했습니다. 이번 RTLLM에서는 둘 다 떨어졌으니 컴파일률 상승을 개선 근거로 쓸 수 없었습니다.
  2. update 총량을 묶으면 망가지지는 않지만, 나아지지도 않을 수 있습니다. 이전 두 실험의 큰 하락은 피했습니다. 대신 효과가 신뢰구간 안에 묻혔습니다.
  3. 판정기의 사각지대가 데이터 분포를 정합니다. 메모리와 래치를 모델링하지 못하는 판정기를 쓰면 FIFO·메모리 데이터가 사라지고, 모델은 그 계열을 배우지 못합니다.
  4. 평균만 보면 놓칩니다. +0.85%p라는 평균 뒤에서 28개 과제가 오르고 25개가 내려갔습니다. 공개 판단은 평균과 신뢰구간으로 했지만, 다음 실험의 방향은 과제별 변화에서 나왔습니다.
  5. 기준을 먼저 묶어야 실패를 실패라고 쓸 수 있습니다. 공개 기준과 결과 분류 문구를 미리 정해 두었기 때문에 모델 카드에 “개선 미입증”이라고 쓰는 데 망설일 여지가 없었습니다.

ThakiCloud 제품 관점: 어디에 쓸 수 있나

이 모델은 ThakiCloud 제품에 통합되어 있지 않습니다. 아래는 적용 가능성이고, 측정하거나 구현한 내용이 아닙니다.

  • Maxis(학습·파인튜닝·소형화): 이번 파이프라인의 각 단계를 도메인 파인튜닝 절차로 옮길 수 있습니다. 행 단위 라이선스 추적, 자기증류 후 형식 검사로 거르기, update 총량 제한, 사전등록 게이트, 병합 정합성 검사가 그 단계들입니다. 정답을 기계로 검증할 수 있는 도메인이라면 RTL이 아니어도 같은 구조가 됩니다.
  • Metis(추론·서빙): 27B bf16 모델을 thinking 모드 64K 출력으로 서빙하는 조건 그대로 평가했습니다. 학습 뒤 평균 출력 토큰이 줄어든 점은 서빙 비용 측면에서 따로 측정해 볼 만한 변화입니다.
  • Paxis(에이전트·업무 자동화): 하드웨어 설계 에이전트라면 모델 한 번의 생성보다 생성 → 시뮬레이션 → 형식 검사 → 수정 루프가 중요합니다. 이번 결과는 모델 가중치만으로 정확도를 끌어올리기 어렵다는 근거이고, 도구 루프로 검증하는 설계 쪽에 무게를 싣습니다.

한계

  • 학습 런은 하나뿐이라 재학습 노이즈를 모릅니다.
  • 평가는 단일 모듈 spec-to-RTL과 Python 코딩입니다. 저장소 단위 설계, 복잡한 FPGA·GPU·NPU 블록은 평가하지 않았습니다.
  • 학습 설명은 원본 코드에서 역생성한 글이라 독립 사양이 아닙니다.
  • 학습 데이터 27행에서 시뮬레이션 차이가 나왔고, 실제 오류율은 확정하지 못했습니다.
  • 과제당 3샘플이라 과제별 변화는 패턴 관찰일 뿐 통계적 결론이 아닙니다.

마치며

Thaki-HW-27B-v0.1은 원본보다 나은 모델이 아니라, 원본을 망가뜨리지 않는 학습 방법을 확인한 체크포인트입니다. 가중치와 함께 데이터 출처 목록, 평가 조건, 한계를 모델 카드에 모두 공개했습니다. RTL 모델을 학습하려는 팀이 같은 함정을 피하는 데 참고가 되면 좋겠습니다.

참고 자료

이 글 공유하기

태그: LLMOps, maxis, metis, paxis, research preview, rtl, verilog, 파인튜닝, 하드웨어 설계

카테고리: ,

업데이트: