들어가며
안녕하세요, 카카오뱅크 AI코어개발팀에서 AI Research Engineer로 근무하고 있는 Yann, Haki입니다.
저희는 금융위원회와 금융보안원이 주최한 2025 금융 AI Challenge 금융보안 AI 모델 경쟁 트랙에 LostCow 팀으로 참가해 Public 리더보드 1위, Private 리더보드 2위를 기록하며 최종 우수상을 수상했습니다.
저희 팀 이름인 LostCow는 취업이 힘들던 시절, “소 잃고 외양간 고치자"는 마음으로 함께 공부하면서 만든 이름입니다.
이후에도 LostCow라는 이름으로 여러 대회에 함께 참가했고, 결국 같은 회사에서 다시 만나 이번 대회까지 함께하게 되었습니다.
이 글은 저희가 여러 제약 조건 속에서 기술적인 문제를 어떻게 해결하며 성과를 이뤄냈는지에 대한 생생한 여정을 담고 있습니다. 대규모 언어 모델(LLM, Large Language Model)을 금융보안 도메인에 맞게 튜닝하고 최적화하기 위해 필요한 데이터 수집부터 학습, 추론 방식까지 구체적으로 공유합니다. LLM을 특정 도메인에 적용하거나 제한된 환경에서 모델 최적화를 고민하는 엔지니어, AI 경진대회에 관심이 있거나 평소 LLM 개발 과정을 궁금해하셨던 모든 분들께 저희 경험이 실질적이고 유용한 힌트가 되기를 바랍니다.
문제 정의 및 접근 방향
대회 목표와 도전 과제
이번 대회의 목표는 금융보안 실무에 직접 활용 가능한 AI 모델 개발입니다. FSKU(Financial Security Knowledge Understanding) 평가지표 문항에 대해 단일 LLM 모델로 객관식과 주관식 문제를 동시에 해결해야 했습니다.
💡 FSKU 평가지표 문항이란?
금융회사가 금융보안 관련 업무에 활용할 AI모델의 성능을 비교하여 최적의 모델을 선정할 수 있도록 금융보안원이 개발한 금융보안 이해도 지표 벤치마크 참고자료
여기서 객관식과 주관식은 완전히 상반된 요구사항을 가집니다. 객관식 문제의 까다로운 점은 정답 번호 하나만 정확히 출력해야 한다는 것입니다. 모델이 실제로 정답을 알고 있더라도, 출력 형태에 따라 정답 후처리에 실패하는 경우가 발생할 수 있습니다.
예를 들어,
• 정답: 1
• 정답은 1번입니다
• 정답으로 추측되는 번호는 4번입니다
• 1번이 가장 적절합니다. 왜냐하면…
위와 같이 다양한 표현이 나올 수 있는데, 이런 응답들을 규칙 기반(Rule-based)으로 안정적으로 파싱하는 것은 매우 어렵습니다. 반면 주관식의 경우는 정반대입니다. 풍부하고 자세한 서술이 필요하고, 정답에 포함된 핵심 키워드를 빠짐없이 포함해야 높은 점수를 받을 수 있습니다.
결국 모델은 객관식에서는 특정 규칙으로 파싱할 수 있는 간결한 응답(예: 정확한 숫자 1토큰), 주관식에서는 풍부하고 상세한 설명을 생성해야 합니다. 이처럼 완전히 상반된 두 가지 응답 패턴을 하나의 모델로 동시에 잘 수행하게 만드는 것이 핵심 과제였습니다.
여기에 하드웨어 제약까지 더해졌습니다.
즉, 24GB에 올라가고, 시간 내에 끝나며, 외부 의존 없이 재현 가능한 모델 중에서 가장 뛰어난 성능을 내는 모델을 만들어야 했습니다.
대회 평가 방식
평가는 객관식과 주관식 점수를 동일한 가중치(50%)로 합산하는 방식으로 이루어졌습니다.
최종 Score = 0.5 × 객관식 점수 + 0.5 × 주관식 점수
﹒ 객관식: 정확도(Accuracy) = 정답 일치 개수 / 전체 객관식 개수
﹒ 주관식: 0.6 × 의미 유사도(Cosine Similarity) + 0.4 × 키워드 재현율
특히, 전략 수립에 큰 영향을 미친 부분은 주관식 점수에서 키워드 재현율의 비중(40%)입니다. 의미적으로 유사한 답변을 하더라도, 정답에 포함된 핵심 용어가 응답에 빠져 있으면 상당한 감점을 받는 구조입니다. 이러한 평가 구조를 고려하여 뒤에서 설명할 BM25 기반의 Retrieval-Augmented Generation(RAG) 전략을 세우게 되었습니다.
팀에서 잡은 접근 방향
이런 제약과 평가 방식을 바탕으로, 저희는 두 가지 큰 전략을 세웠습니다.
2. 답변 시 문서 근거를 명확히 제시해 신뢰성을 높힌다. (BM25 기반 RAG)
즉, 모델이 도메인 지식을 충분히 내재화하는 동시에 실제 추론 단계에서는 외부 문서를 근거로 삼아 정확성과 신뢰성을 이중으로 확보하는 구조입니다. 이제 다음 섹션부터는 각 전략을 단계별로 자세히 설명하겠습니다.
모델 선정 기준과 이유
24GB VRAM(Video Random Access Memory)이라는 제약 내에서 최대 성능을 낼 수 있는 모델을 찾는 것이 핵심이었습니다. 일반적으로 LLM을 선정할 때는 벤치마크 성능이 가장 중요하지만, 이번에는 먼저 물리적으로 실제 구동이 가능한지가 가장 우선적인 기준이었습니다.
한국어 능력이 뛰어난 오픈소스 모델들을 집중적으로 탐색한 뒤, Qwen3-8B, Qwen3-14B, Qwen3-30B-A3B, Exaone-4.0 등 여러 모델을 실제로 테스트해 보았고, 최종적으로 Qwen3-30B-A3B-Instruct-2507을 선정하게 되었습니다.
모델을 Qwen3-30B-A3B-Instruct-2507로 선정하게 된 이유로는 우선, 한국어 능력과 장문 처리에 적합하여 선정했습니다. 금융보안 법령은 일반적인 한국어 텍스트와는 다른 특성을 지닙니다. 한 조항이 수백 자에 달하고, 복잡한 참조 구조가 빈번하게 나타납니다. (ex. 제1항의 규정에도 불구하고 제2항 단서에 해당하는 경우에는…) 이런 텍스트를 제대로 이해하려면 단순히 한국어를 지원하는 수준이 아니라, 긴 문맥 속 조건절과 참조 관계까지 정확히 파악할 수 있어야 합니다. Qwen3 시리즈는 여러 한국어 벤치마크에서 모델 크기 대비 높은 성능을 보였으며, 최대 128K 토큰 컨텍스트 윈도우를 지원해 장문 법령 처리에 적합했습니다.
두 번째로는 MoE 구조로 성능과 자원 균형 확보가 가능하여 선택하였습니다. Qwen3-30B-A3B의 핵심은 MoE(Mixture-of-Experts) 구조입니다. 일반 Dense 모델은 모든 파라미터가 연산에 참여하지만, MoE 구조에서는 Gate 네트워크가 128개 전문가 중 8개만 선택해 활성화합니다. 총 파라미터는 30B이지만, 실제 추론 시에는 약 3B만 사용되어 큰 모델의 지식 용량과 작은 모델의 연산 효율성을 모두 확보할 수 있었습니다. 24GB GPU 환경에서 30B급 모델을 사용할 수 있었던 것도 이 MoE 구조 덕분입니다.
마지막으로 Qwen 시리즈는 가중치가 완전 오픈되어 있으며 상업적 활용 가능 라이선스를 제공하고, 커뮤니티도 활발하게 업데이트되고 있습니다. 이번 대회에서 금융보안 튜닝 레시피를 확보하면, 향후 Qwen 시리즈가 업데이트될 때 손쉽게 마이그레이션할 수 있다는 점도 고려해 해당 모델을 선택하게 되었습니다.
Thinking 모델 vs Instruct 모델
Qwen3-30B-A3B에는 Thinking과 Instruct 두 가지 버전이 있습니다. Thinking 버전은 답변 전 <think>...</think> 태그 안에서 내부 추론 과정을 먼저 생성하고, 그 결과를 바탕으로 최종 답변을 출력합니다.
한마디로, Chain-of-Thought 추론이 모델 자체에 내장된 형태라고 볼 수 있습니다.
언뜻 보면 Thinking 모델이 더 정확할 것 같지만, 저희가 구성한 환경에서는 두 가지 문제가 있었습니다.
2. Thinking 모델의 내부 추론 패턴이 팀에서 적용한 CPT 학습과 충돌하는 현상이 있었음
이와 관련된 자세한 내용과 수치는 아래 실험 결과에서 더 상세히 설명드리겠습니다.
2단계 도메인 특화 학습
모델을 선정한 후에는, 범용 모델에 금융보안 지식을 주입하는 Domain Adaptation(도메인 적응) 단계가 진행됩니다. LLM을 특정 도메인에 적응시키는 방법은 크게 두 가지가 있습니다. 도메인 텍스트를 추가로 학습시켜 모델이 해당 도메인의 언어와 지식을 내재화하도록 하는 CPT(Continual Pre-Training) 와, 질문-답변 형식의 데이터로 모델의 응답 패턴을 학습시키는 SFT(Supervised Fine-Tuning) 입니다.
저희는 이 중 CPT를 주요 학습 전략으로 선택하였고 2단계의 CPT를 적용하였습니다.
정리하자면, 저희의 CPT 전략은 단순히 도메인 텍스트를 추가로 학습시키는 것이 아니라, 학습 순서와 데이터 성격, 파라미터 업데이트 범위까지 모두 설계하여 catastrophic forgetting(치명적 망각)을 통제하면서 도메인 지식을 효과적으로 주입하는 데에 초점을 맞췄습니다.
Stage-1: 법령 중심 CPT
첫 번째 단계에서는 법령 데이터를 중심으로 모델을 학습시켰습니다. 법령은 금융보안의 기준선 역할을 하며, ‘이것은 허용되고, 저것은 금지된다’와 같은 엄밀한 정의와 규정이 모두 법령에 담겨 있습니다.
- • 학습 데이터: 개인정보보호위원회, 과학기술정보통신부, 금융위원회, 한국인터넷진흥원에서 공개한 법령 중 ‘금융’ 키워드를 포함한 모든 법령
- • 목적: 금융보안의 정의, 원칙, 금지 조항을 정확히 학습시키고, ‘~하여야 한다’, ‘~에 해당하는 경우에는’과 같은 법령 특유의 엄밀한 표현과 용어 체계를 내재화하는 것
이 과정을 통해 모델은 금융보안이란 무엇이고, 무엇이 되고 무엇이 안 되는지에 대한 기본적인 뼈대를 갖추게 됩니다.
Stage-2: 가이드라인 중심 CPT
두 번째 단계에서는 가이드라인과 안내서를 중심으로 모델을 학습시켰습니다. 가이드라인은 법령의 내용을 실무자가 이해하고 적용할 수 있도록 쉽게 풀어 설명한 문서입니다. 법령이 무엇을 해야 하는지 규정한다면, 가이드라인은 어떻게 해야 하는지를 절차와 사례를 통해 보여줍니다.
- • 학습 데이터: 개인정보보호위원회, 한국인터넷진흥원의 안내서·가이드라인 PDF
- • 목적: 절차적 설명과 사례 중심의 표현력을 학습하고, 주관식 문제에 대응할 수 있는 서술 능력을 강화
여기서 법령을 먼저, 가이드라인을 나중에 학습한 데에는 이유가 있었는데요, 가이드라인은 친절하게 설명하지만, 법령처럼 엄밀한 기준을 직접 제공하지는 않습니다. 만약 가이드라인을 먼저 학습하면 모델이 설명하는 톤을 먼저 익힌 상태에서 법령의 엄밀한 기준을 덮어씌우게 되는데, 이 경우 앞서 익힌 설명 톤이 손상될 수 있습니다. 반대로 기준을 먼저 세우고(법령), 그 위에 설명하는 톤을 얹는(가이드라인) 순서로 학습하면, 법령 지식이라는 견고한 토대 위에 자연스러운 표현력이 더해져 더욱 안정적인 학습이 가능했습니다.
catastrophic forgetting을 통제하기 위한 전략: LoRA 적용 전략
앞서 CPT의 핵심 리스크로 catastrophic forgetting을 언급한 바 있습니다. 30B 모델의 전체 파라미터를 업데이트하면 도메인 지식은 주입되지만, 기존에 모델이 갖고 있던 일반 지식이나 언어 능력이 손상될 수 있다는 문제가 있습니다. Low-Rank Adaptation(LoRA)는 이러한 문제를 구조적으로 완화해주는 방법입니다. 원본 가중치는 고정(freeze)하고, 학습 가능한 변화량을 저차원(low-rank) 공간으로 제한함으로써, 도메인 방향으로의 조정은 허용하되 모델이 원본 상태에서 크게 벗어나지 않도록 regularization 장치로서 LoRA를 활용하는 것입니다.
LoRA의 기본 아이디어는 간단합니다. 모델의 가중치 행렬 $W$를 직접 업데이트하는 대신, 작은 저차원 행렬 $A$와 $B$를 학습해서 $W + A×B$ 형태로 원본 가중치를 조정합니다. 예를 들어, 원본 행렬이 $4096×4096$(약 1,670만 파라미터)이라면, Rank 128 기준으로 $A(4096×128)$와 $B(128×4096)$만 학습하면 됩니다. 이렇게 하면 학습 파라미터가 약 104만 개로, 전체 파라미터의 약 6%만 학습하면서도 도메인 방향으로 모델을 효과적으로 조정할 수 있습니다.
이번 솔루션에서 특히 중요했던 설계는 Stage-1과 Stage-2에서 LoRA를 적용하는 레이어의 범위를 다르게 설정했다는 점입니다.
Stage-1 (법령): 넓은 범위, 강한 지식 주입
Stage-1의 목표는 금융보안 법령이라는 새로운 도메인 지식을 모델에 깊이 새기는 것이었기에 LoRA 적용 범위를 최대한 넓게 설정했습니다.
- • LoRA 적용 대상: 모든 MLP(Multi-Layer Perceptron, 다층 퍼셉트론) 레이어 + MoE Gate 레이어 + 임베딩 레이어
- • 학습 파라미터: 원본 파라미터의 약 18%
- • 하이퍼파라미터: Rank=128, 높은 Rank에서의 학습 안정성을 위해 rsLoRA(rank-stabilization LoRA) 적용
MLP 레이어를 포함한 이유는, Transformer 구조에서 MLP 레이어가 사실상 지식을 저장하는 창고 역할을 한다고 알려져 있기 때문입니다.2 3
새로운 도메인 지식을 효과적으로 주입하려면 이 창고를 직접 건드릴 필요가 있습니다. 임베딩 레이어까지 적용 범위를 확장한 것은, 법령에 등장하는 도메인 특화 용어(전자금융거래법, 개인신용정보 등)의 토큰 표현 자체를 조정하기 위한 목적입니다. 범용 모델이 학습한 일반적인 토큰 임베딩만으로는 이런 전문 용어의 뉘앙스를 충분히 반영하기 어렵기 때문입니다.
또, Rank는 128로 설정했는데, 이렇게 높은 Rank에서는 일반 LoRA의 학습 곡선이 불안정해질 수 있어 이를 보완하기 위해 rsLoRA를 적용하였습니다. rsLoRA는 Rank에 따라 스케일링 팩터를 조정해서 높은 Rank에서도 안정적으로 수렴할 수 있도록 지원합니다.
Stage-2 (가이드라인): 좁은 범위, 표현력만 보강
Stage-2에서는 반대로 LoRA 적용 범위를 극도로 좁혔습니다. Query와 Value Attention Projection 레이어만 대상으로 삼아 원본 파라미터의 약 2%만 학습하도록 설계했습니다.
- • LoRA 적용 대상: Query, Value Attention Projection Layer
- • 학습 파라미터: 원본 파라미터의 약 2%
데이터 전처리와 BM25 RAG
모델 학습 전략을 세운 후에는 데이터 확보가 매우 중요한 과제였습니다. 이번 대회에서는 학습 데이터가 별도로 제공되지 않았기 때문에, 어떤 데이터를 어디서 가져올지부터 직접 결정해야 했습니다.
금융보안 지식의 원천은 결국 두 가지로 수렴한다고 생각했습니다. 하나는 법령이고, 다른 하나는 그 법령을 실무에 적용할 수 있도록 풀어 쓴 가이드라인/안내서입니다.
법령은 ‘무엇이 되고 무엇이 안 되는지’를 정의하고, 가이드라인은 ‘그래서 실무에서 어떻게 해야 하는지’를 친절하게 설명합니다. 대회 문제 역시 이 두 가지 층위의 지식을 모두 요구하고 있었기 때문에, 데이터 수집도 이 두 축을 중심으로 진행했습니다.
법령 데이터는 개인정보보호위원회, 과학기술정보통신부, 금융위원회, 한국인터넷진흥원에서 공개한 법령 중 금융 키워드를 포함한 자료를 수집하였고, 가이드라인 데이터는 개인정보보호위원회와 한국인터넷진흥원에서 제공하는 안내서 및 가이드라인 PDF를 확보했습니다. 모두 공개된 자료이며, 오프라인 환경이라는 대회 제약에 맞춰 사전에 준비해 두었습니다.
이렇게 수집한 데이터는 CPT 학습용과 RAG 검색용, 두 가지 목적으로 활용됩니다. 같은 원본 데이터라도 각각의 목적에 따라 전처리 방식이 달라지며, 이 차이가 실제 성능에 중요한 영향을 미쳤습니다.
법령 데이터 전처리
법령은 법 → 장 → 조 → 항 → 호 순서의 명확한 계층 구조를 가지고 있기 때문에, 전처리 과정이 비교적 수월하게 진행되었습니다.
전처리의 핵심은 조(條) 단위로 분리하면서 법령명 접두어를 반드시 유지하는 것이었습니다.
법령에서 하나의 ‘조’는 독립적인 규정을 담고 있는 최소 의미 단위로, 이를 {법령명}\n{조}\n{항} 형식으로 구성하면 모델이 해당 조항의 내용뿐 아니라 이 조항이 어느 법에 속하는지까지 맥락을 함께 학습할 수 있습니다.
예를 들어, 같은 ‘제3조’라도 개인정보보호법 제3조와 전자금융거래법 제3조는 완전히 다른 내용을 담고 있기 때문에, 법령명 접두어는 모호성을 해소하는 데 필수적인 요소였습니다.
메타 정보 처리도 신경 써서 진행했습니다. 개정 이력, 신설, 폐지 등은 학습에 노이즈가 될 수 있어 필터링했지만, <개정날짜>는 현재 시점의 법적 효력을 판단하는 데 필요하므로 보존하였습니다. 또한 PDF에서 텍스트를 추출하는 과정에서 흔히 발생하는 띄어쓰기 오류, 문장 단절, 중간 개행 삽입 등의 문제도 정규화를 통해 보완하여 데이터 품질을 높였습니다.
가이드라인 데이터 전처리: CPT용과 RAG용은 다르게
가이드라인 데이터에서 특히 중요했던 설계 포인트는 CPT용 데이터와 RAG용 데이터의 전처리 방식을 다르게 설계한 것입니다. 같은 원본 문서를 활용하더라도, 학습에 사용할 데이터와 검색에 사용할 데이터는 요구사항이 다르기 때문입니다.
1. CPT용 전처리: 원문 분포와 문맥 보존
CPT의 목적은 모델이 도메인 특유의 문체와 구조를 온전히 습득하도록 하는 데 있습니다. 문장의 흐름, 설명의 전개 방식, 사례 제시 패턴 등을 온전히 학습할 수 있도록, 원문의 흐름을 최대한 보존하는 것이 중요합니다. 이를 위해 토큰 길이(2048)에 맞춰 청킹하되, 각 청크마다 해당 섹션의 제목을 포함시켜 맥락이 유지되도록 했습니다. 또한 그림 추출 후 남은 불완전한 텍스트, 제어문자, 인코딩 오류 등 명백한 노이즈만 제거하고, 원문의 구조와 흐름은 최대한 살렸습니다.
2. RAG용 전처리: BM25 검색 품질을 위한 강력한 정규화
RAG용 데이터는 목적이 CPT와 완전히 다릅니다.
BM25는 키워드 매칭 기반의 검색 알고리즘이기 때문에, 문서에 이상한 문자나 노이즈가 남아 있으면 검색 품질이 직접적으로 저하됩니다.
예를 들어, PDF에서 추출할 때 함께 딸려오는 CSS 잔여물(font-size: 12px; 등)이나 깨진 인코딩 문자가 존재하면, 이들이 BM25의 term frequency 계산에 악영향을 미치게 됩니다.
이러한 문제를 해결하기 위해, 제어문자 제거, 개행/공백 정규화, CSS/HTML 잔여물 제거, 연속 반복 문자 제거, 한글 비율 및 공백 비율 기반 필터링 등 총 13단계의 필터링 규칙을 순차적으로 적용했습니다. 이렇게까지 강력하게 정제하는 이유는, 검색 단계에서의 실패가 이후 LLM의 응답 품질에 연쇄적으로 영향을 미치기 때문입니다. 검색이 잘못된 문서를 반환하면 모델이 이를 참고해 틀린 답을 생성하게 되고, 최악의 경우 환각(Hallucination)까지 발생할 수 있습니다.
13단계 필터링 규칙 및 문장 단위 분할·패킹 적용
• 개행 및 공백 정규화 (\r\n\n), 다중 공백/개행 축소
• 괄호 태그(예: 비매품 등 짧은 태그 문자) 제거
• CSS/HTML 스타일 블록, 중괄호, 세미콜론 다수 제거
• 연속 문자 8회 이상 반복 제거
• 공백 없는 장문(25자 이상) 제거
• 두 글자 이내 외국어와 한글이 결합된 텍스트 제거
• 총 길이 20 이상에서 한글 비율이 10 미만인 텍스트 제거
• 총 길이 80 이상에서 공백 비율이 2 이상인 텍스트 제거
• 한글, 외국어, 숫자, 한자, 문장부호가 결합되어 총 문단 내 60% 이상 차지하는 텍스트 제거
• 영문 및 숫자 비율이 20%를 초과하는 텍스트 제거
• 숫자, 영문, 한글 중 하나 이상이 포함되지 않는 텍스트 제거
이처럼 전처리 방식을 강하게 적용한 결과, 실제 성능 수치에서도 명확한 개선 효과를 확인할 수 있었습니다.
같은 원본 데이터를 사용하더라도, CPT용 전처리 데이터를 RAG에 사용했을 때와 RAG 전용 전처리를 적용했을 때 4.5%p의 성능 차이가 발생했습니다. ‘데이터 품질이 모델 성능을 좌우한다’는 말이 검색 파이프라인에서도 그대로 적용된 셈입니다.
BM25 기반 RAG: 왜 키워드 검색인가?
모델이 학습을 통해 도메인 지식을 내재화했더라도, 추론 시점에 외부 문서를 참조하면 정확도를 더욱 높일 수 있습니다. 이 역할을 담당하는 것이 바로 RAG(Retrieval-Augmented Generation)입니다. 질문과 관련된 문서를 검색하여 LLM 입력에 함께 제공하면, 모델은 자신의 내재 지식과 검색된 문서를 종합해 더욱 근거 있는 답변을 생성할 수 있습니다.
RAG에서 문서 검색 방식은 크게 두 가지로 나뉩니다. 텍스트를 벡터로 변환해 의미적 유사도를 계산하는 임베딩 기반 검색(Dense Retrieval) 과, 문서 내 특정 키워드 출현 빈도를 기반으로 점수를 매기는 BM25(Sparse Retrieval) 입니다. 최근 RAG 구현에서는 임베딩 기반 검색이 주로 사용되지만, 저희는 BM25 방식을 선택했습니다.
청킹 전략 및 Top-k 최적화
BM25 검색의 품질은 문서를 어떻게 분할(청킹)하느냐와, 검색 결과에서 몇 개를 선택(Top-k)하느냐에 크게 좌우됩니다.
청킹에는 Sliding Window 방식을 적용했습니다. 최대 청크 크기는 1,000 tokens, 오버랩은 100 tokens으로 설정했습니다. 오버랩을 둔 이유는 청크 경계에서 맥락이 단절되는 것을 막기 위함입니다. 예를 들어, 하나의 법률 조항이 두 개의 청크에 걸쳐 분리되더라도, 100 토큰의 오버랩 구간 덕분에 앞뒤 맥락이 자연스럽게 이어집니다.
검색 인덱싱 단계에서는 형태소 분석(MeCab) 기반 토크나이징을 적용했습니다. 한국어는 교착어 특성상 개인정보보호법’을’, 개인정보보호법’에서’, ‘개인정보보호법’의’처럼 하나의 단어에 다양한 조사가 결합됩니다. 원문 그대로 인덱싱하면 같은 단어임에도 조사 차이 때문에 매칭이 실패할 수 있지만, MeCab으로 형태소를 분리하면 ‘개인정보보호법’ + ‘을/에서/의’로 구분되어 조사와 상관없이 핵심 키워드를 정확하게 매칭할 수 있습니다.
Top-k는 검색된 문서 중 상위 몇 개를 LLM 입력에 포함시킬지 결정하는 하이퍼파라미터입니다. 많이 넣을수록 정보량은 많아지지만, 컨텍스트 길이가 길어지면서 노이즈도 증가하고 메모리 사용량도 커집니다.
실험 결과, Top-k=10이 최적점이었습니다. Top-k=5에서는 필요한 정보를 놓치는 경우가 있었고, Top-k=20부터는 관련 없는 문서가 혼입되면서 오히려 성능이 소폭 하락했습니다. Top-k=40에서는 평균 토큰 수가 15,000을 넘어서 OOM(Out-of-Memory) 오류까지 발생했습니다. 이 경험을 통해 조금이라도 더 넣자 보다는 안정적으로 끝까지 돌릴 수 있는가가 더 중요하다는 교훈을 얻었습니다.
엔지니어링 최적화 방안으로 택한 양자화와 추론 최적화
지금까지 학습 전략(CPT + LoRA)과 검색 전략(BM25 RAG)에 대해 살펴봤습니다. 이제 이 모든 과정을 24GB GPU 환경에서 실제로 동작하게 만들기 위한 엔지니어링 최적화 방안에 대해 설명하겠습니다.
Auto-Round 4bit 양자화
양자화(Quantization)는 모델 가중치를 더 적은 비트로 표현해 메모리 사용량을 줄이는 기법입니다. 원래 32bit(FP32)나 16bit(FP16)로 표현되는 가중치를 8bit 또는 4bit로 압축하면 GPU 메모리를 크게 절약할 수 있습니다. 다만 비트 수가 줄어들수록 표현 정밀도가 떨어지고, 이로 인해 성능 손실이 발생할 수 있습니다. 결국 양자화의 핵심은 정밀도 손실을 최소화하면서 메모리를 얼마나 줄일 수 있는가에 있습니다.
이 과정에서 저희는 Auto-Round 4bit 양자화를 선택했습니다. 기존 대표적 양자화 방식(GPTQ, AWQ 등)은 Data Calibration 과정이 필요합니다. 샘플 데이터를 모델에 통과시켜 가중치 분포를 파악하고 그에 맞춰 양자화 스케일을 결정하는 방식인데, 이 과정에서 샘플링 편향으로 분포가 왜곡되거나 재현성이 떨어질 수 있습니다.
Auto-Round는 이와 달리 Sign-Gradient Descent 기반으로 동작하며, RTN(Round-to-Nearest) 방식을 채택해 별도의 Calibration 데이터 없이도 높은 정밀도를 유지합니다. 이는 재현성 측면에서도 유리한 측면이 있습니다.
여기서 한 가지 중요한 전략을 더 적용했습니다. 바로 전체 가중치는 4bit로 양자화하되, MoE Gate Layer만은 16bit로 선택적으로 보존한 것입니다.
Gate Layer는 MoE 구조에서 토큰을 어떤 Expert에게 보낼지 결정하는 라우터 역할을 합니다. 앞서 설명한 것처럼 Qwen3-30B-A3B는 128개 Expert 중 8개만 활성화하는데, 이 선택을 담당하는 것이 바로 Gate Layer입니다.
Gate의 정밀도가 낮아지면 토큰이 엉뚱한 Expert로 라우팅되어, 한번 잘못된 Expert로 보내진 토큰은 이후 전체 출력 품질에 연쇄적으로 악영향을 미칠 수 있습니다.
실제로 Gate까지 4bit로 양자화했을 때 라우팅이 불안정해지는 현상을 확인했고, Gate만 16bit로 유지함으로써 이 문제를 해결할 수 있었습니다.
출력 제어: Structured Output
모델을 양자화하여 GPU에 올린 후, 마지막으로 해결해야 할 과제는 출력 품질을 어떻게 제어할 것인가였습니다. 앞서 객관식과 주관식 문제의 요구하는 출력 형태가 완전히 달랐기 때문에, 두 유형에 대해 각각 다른 전략을 적용했습니다.
객관식: Structured Output 적용
객관식에서 가장 위험한 실패 케이스는, 모델이 정답을 알고 있음에도 설명을 덧붙여 후처리 과정에서 오답으로 처리되는 상황입니다. 이런 문제를 원천적으로 차단하기 위해 xgrammar를 활용한 Structured Output을 도입했습니다. JSON 스키마로 출력 토큰 자체를 제약하여, 정답 번호 이외의 다른 토큰은 아예 생성되지 않도록 설계했습니다. 또한 객관식이 4지 또는 5지선다로 출제되는 만큼, 이 방식으로 4지선다 문제에서 5번 등 존재하지 않는 보기가 출력되는 현상도 방지할 수 있습니다.
위 방식을 사용하면 후처리 파싱이 전혀 필요하지 않습니다. 모델의 출력 자체가 곧 정답 번호이기 때문입니다.
주관식: 자유 생성
반면 주관식에는 Structured Output을 적용하지 않았습니다. Logit 제한이 걸리면 모델이 자연스러운 문장을 생성하기 어려워지고, Stage-2 CPT를 통해 학습한 설명적 표현력을 충분히 발휘하지 못하기 때문입니다. 주관식의 평가 기준이 의미 유사도와 키워드 재현율인 만큼, 모델이 자유롭게 생성하되 RAG로 근거를 제공하는 접근이 더 효과적이었습니다.
이처럼 문제 유형에 따라 Structured Output 적용 여부를 동적으로 제어함으로써, 객관식과 주관식 각각에 최적화된 출력을 생성할 수 있었습니다.
실험 결과
지금까지 설명한 여러 기술 선택들이 실제로 어떤 성능 차이를 만들어냈는지, 실험 결과를 통해 검증해보았습니다. 각 실험은 비교하려는 변수 외의 조건을 최대한 동일하게 맞춘 상태에서 진행했습니다.
1. 모델 크기별 성능
가장 먼저 확인한 것은 베이스 모델 자체의 성능 차이였습니다. CPT, RAG 등 별도의 기법을 적용하지 않은 순수 Instruct 모델 상태에서, 4bit 양자화만 적용한 뒤 동일한 프롬프트로 평가를 진행했습니다.
실험 결과, 모델 크기가 커질수록 성능이 향상되는 경향이 뚜렷하게 나타났습니다. 특히 Qwen3-30B-A3B는 MoE 구조 덕분에 24GB GPU 환경에서도 구동이 가능하면서 가장 높은 기본 성능을 보여주었습니다. 이 결과는 앞서 언급한 같은 메모리 예산이면 큰 모델을 4bit로 쓰는 게 낫다는 판단을 뒷받침해줍니다.
2. LoRA vs Full Fine-Tuning
다음으로 학습 방식에 따른 성능 차이를 비교했습니다. 동일한 Qwen3-30B-A3B 모델에 동일한 법령+가이드라인 데이터를 활용해 2단계 CPT를 수행하되, 파라미터 업데이트 방식만 LoRA와 Full Fine-Tuning으로 달리 적용했습니다.
실험 결과, Full Fine-Tuning이 더 많은 파라미터를 학습했음에도 불구하고 LoRA가 더 높은 성능을 보였습니다. 직관적으로는 다소 의외일 수 있지만, 앞서 언급한 맥락을 고려하면 그 이유를 이해할 수 있습니다. 금융보안 법령은 원문의 정확한 표현 그대로 기억하는 것이 중요한 도메인입니다. Full Fine-Tuning으로 전체 파라미터를 강하게 업데이트하면, 기존의 일반 지식이나 언어 능력이 훼손되어(catastrophic forgetting) 오히려 성능이 저하될 수 있습니다. 반면 LoRA는 저차원 부분공간에서만 업데이트를 허용하므로 이러한 위험을 자연스럽게 억제할 수 있습니다.
3. 검색 방법별 성능
이번엔 CPT(LoRA)까지 완료된 동일한 모델을 기반으로, 추론 시 검색 방법만 다르게 적용해 성능을 비교했습니다. Embedding 검색에는 별도의 임베딩 모델을 사용했고, Hybrid는 BM25와 Embedding 검색 결과를 결합한 방식입니다. Top-k=10, 동일한 RAG 전처리 데이터를 사용했습니다.
RAG를 적용하는 것만으로도 성능이 크게 향상되었으며(최소 +4.6%p 이상), 그 중에서도 BM25 단독 사용이 가장 높은 성능을 보였습니다. Hybrid가 BM25 단독보다 낮은 성능을 보인 이유는, 임베딩 기반 검색이 의미적으로는 유사하지만 실제로는 정확하지 않은 문서를 가져오면서 노이즈로 작용했기 때문으로 분석됩니다.
4. 학습 방식 및 Thinking 여부
모델 아키텍처(Thinking vs Instruct)와 학습 방식(CPT vs SFT)의 조합을 비교한 결과입니다. 모든 실험은 동일한 데이터셋을 기반으로, BM25 RAG(Top-k=10)를 적용한 상태에서 진행되었습니다.
SFT 데이터는 전처리된 법령과 가이드라인 문서 청크를 바탕으로 DeepSeek-R1 모델을 활용해 Synthetic Q&A 데이터를 생성했습니다. Thinking + SFT의 경우, DeepSeek-R1이 생성한 한국어 추론 과정을 포함시켜 기존 모델의 <think> 출력 구조와 동일한 형태로 학습 데이터를 구성했고, Instruct + SFT에는 추론 과정을 제외한 답변만으로 데이터를 구성했습니다.
위 표에서 가장 주목할 만한 결과는 두 가지입니다.
첫째, Thinking + CPT 조합의 성능이 0.5625로 현저히 낮다는 점입니다. 이는 앞서 언급한 Thinking 패턴과 CPT의 충돌 때문입니다.
Thinking 모델은 <think> 태그 안에서 추론 과정을 먼저 생성하도록 학습되어 있는데, CPT로 줄글 형태의 법령 텍스트를 학습시키면 이 내부 추론 패턴이 깨집니다.
결과적으로 추론 능력과 법령 지식 모두 중간 상태에 머무르게 됩니다.
반면 SFT는 질문-답변 형식이라 Thinking 패턴과의 형식적 충돌이 상대적으로 적어 결과적으로 Thinking + SFT 조합이 더 나은 성능(0.6275)을 보였습니다.
둘째, Instruct 모델에서는 CPT가 SFT보다 훨씬 우수한 성능을 보였다는 점입니다(0.6723 vs 0.6150). 이 부분이 저희가 CPT를 주력 전략으로 선택한 근거이기도 합니다. Instruct 모델은 이미 instruction following 능력이 충분히 내재되어 있어, SFT로 추가 학습하는 것보다 CPT로 도메인 지식 자체를 강화하는 것이 훨씬 효과적이었습니다.
5. 전체 성능 개선 흐름
마지막으로, 각 기술을 순차적으로 적용했을 때 누적 성능이 어떻게 변하는지 살펴보았습니다. Qwen3-30B-A3B Instruct 모델을 기준으로, 각 단계를 하나씩 추가하며 측정했습니다.
Base 모델 대비 총 +6.8%p 향상을 달성했습니다. 가장 큰 폭의 개선은 Stage-2 CPT 단계에서 나타났는데, 이는 주관식 문제 해결에 필요한 서술 능력과 표현력이 이 단계에서 크게 강화되었기 때문입니다. RAG의 증분(+0.9%p)은 상대적으로 작아 보일 수 있지만, 이미 CPT로 높아진 베이스라인 위에서의 추가 개선이라는 점과 객관식 문제의 정답 안정성 측면에서의 기여를 함께 고려해야 합니다.
마무리하며
이번 대회를 통해 24GB 단일 GPU라는 제약 안에서 금융보안 도메인 특화 모델을 만드는 전체 파이프라인을 직접 설계하고 검증할 수 있었습니다. MoE 구조 모델 선정, 2단계 CPT, 단계별 LoRA, BM25 기반 RAG, 선택적 Quantization, Structured Output 등 모든 기술이 각각 독립적으로 작동한 것이 아니라, 하나의 일관된 전략 아래에서 유기적으로 맞물려 시너지를 발휘한 결과입니다.
돌이켜보면 모든 기술 선택의 출발점은 최신 트렌드가 아니라 주어진 제약 조건이었습니다. CPT를 선택한 것은 법령 문체의 특수성 때문이었고, BM25를 택한 것은 금융 용어의 정확성이 의미적 유사성보다 중요했기 때문입니다. 또한 LoRA의 적용 범위를 단계별로 다르게 설정한 것도 catastrophic forgetting을 효율적으로 통제하기 위한 결정이었습니다.
‘무엇을 쓸까’보다 ‘왜 이걸 써야 하는가’ 를 먼저 고민했던 점이 결과적으로 좋은 선택으로 이어졌다고 생각합니다.
사실 대회 문제를 처음 접했을 때 약간의 기시감이 들었습니다. 카카오뱅크에서는 전 직원이 금융보안 관련 교육을 정기적으로 이수하고 평가를 받는데, 대회 문제가 그 시험과 꽤 닮아 있었기 때문입니다. 평소에 저희가 직접 풀던 문제들을 이번에는 AI에게 맡겨서 해결하게 했다는 점이 인상적이었습니다.
이 덕분에 도메인에 대한 이해도가 이미 어느 정도 갖춰져 있었고, 어떤 문제는 조문을 정확히 알아야 하고, 어떤 문제는 사례를 설명할 수 있어야 정답을 맞출 수 있겠다는 판단을 빠르게 내릴 수 있었습니다. 금융보안 시험 공부가 대회 실전에서 도움이 될 줄은 예상하지 못했습니다.
비슷한 제약 환경에서 도메인 특화 AI를 고민하는 분들께 이 글이 조금이나마 도움이 되었으면 좋겠습니다. 길을 잃어도 결국 답을 찾는 LostCow처럼, 여러분의 여정도 좋은 결과로 이어지길 바랍니다! 🐄
지금까지 긴 글 읽어주셔서 감사합니다.
Reference (더보기)
- LoRA: Low-Rank Adaptation of Large Language Models (Edward J Hu et al., ICLR 2022)
- Efficient Continual Pre-Training for Building Domain Specific Large Language Models (Xie, Y et al., ACL Findings 2024)
- How Useful is Continued Pre-Training for Generative Unsupervised Domain Adaptation? (Uppaal, R et al., RepL4NLP Workshop at ACL 2024)
- Optimize Weight Rounding via Signed Gradient Descent for the Quantization of LLMs (Cheng et al., Findings 2024)
- QLoRA: Efficient Finetuning of Quantized LLMs (Tim Dettmers et al., NeurIPS 2023)