마디순수 Rust 로 만든 한국어 형태소 분석기
문장을 어절로, 어절을 형태소로 나누고 세종 품사 표지를 붙입니다. 국립국어원 모두의 말뭉치 형태 분석 지침을 따릅니다. Python 패키지, Rust 라이브러리, 명령줄 도구가 모두 같은 결과를 냅니다.
madi 기본 설정(사전 + n-gram LM + 신경망 LM)의 실제 출력입니다. 겹줄은 어절 경계, 표지에 마우스를 올리면 정식 이름이 보입니다. 축약된 활용형(신다 = 시 + ㄴ다, 들어 = 듣 + 어)은 원형으로 풀어 냅니다.
무엇을 하나
모두의 말뭉치 지침을 따르는 분석
세종 품사 표지(NNG, VV, EF …)로 분석합니다. 2018 지침이 기본이고, 2025년판 형태 분석 지침식 출력(복합 명사 합치기 등)도 고를 수 있습니다.
두 단계 탐색
사전으로 격자를 만들고, 연접 비용으로 가망 없는 후보를 거른 뒤 형태소 n-gram LM 과 작은 신경망 LM 으로 다시 채점합니다. 앞뒤 양방향 점수로 한 번 더 걸러 LM 질의를 줄입니다.
정밀 모드
점수 차가 작은 어절만 작은 트랜스포머 교사로 다시 고릅니다. 동사·형용사, 불규칙 활용처럼 헷갈리는 자리에서 정확도가 오르고, 대신 느려집니다.
형태소로 나누는 문장 분리
마침표가 없는 구어 문장도 종결 어미를 보고 나눕니다. 규칙만 쓰는 빠른 분리도 함께 있습니다.
사용자 사전
단어, 기분석 항목, 분석 고치기 규칙을 파일로 더할 수 있습니다.
판본 문자열
사전·모델 파일과 설정을 해시로 묶은 문자열(0.2.1+decdb.r3p.f11…)을 냅니다. 두 분석 결과가 같은 판에서 나왔는지 바로 확인할 수 있습니다.
설치
pip install madipy
import madi
m = madi.Analyzer() # 처음 한 번 모델을 받는다
m.pos('아버지가 방에 들어가신다')
# [('아버지', '일반명'), ('가', '주격조'), …]
m.pos('아버지가', tags='code')
# [('아버지', 'NNG'), ('가', 'JKS')]설치 이름은 madipy, 코드에서는 import madi. 모델(약 87 MB, 정밀 모드 +27 MB)은 처음 쓸 때 받습니다.
사용법
분석
tokenize 는 위치·어절 번호·문장 번호·원형이 든 Token 목록을, pos 는 (형태, 품사) 목록을 돌려줍니다. 문자열 목록을 주면 여러 스레드로 나눠 분석합니다.
문장 분리
split_into_sents 는 마침표가 없어도 종결 어미 뒤에서 끊고, 문장마다 원문 위치와 형태소를 줍니다.
여러 후보
analyze(text, top_n=3) 은 점수가 붙은 후보 분석을 좋은 것부터 돌려줍니다.
사용자 사전·불용어
사전 파일을 주거나 add_user_word 로 실행 중에 단어를 더합니다. madi.utils.Stopwords 로 조사·어미 같은 말을 뺍니다.
메서드 이름과 결과 꼴은 Kiwi(kiwipiepy)와 맞춰 두었습니다. 예와 출력이 모두 든 사용 안내는 PyPI 페이지에 있습니다.
성능
여러 분석기를 같은 잣대로 채점했습니다. 각 분석기의 태그를 세종 태그로 옮기고, 복합 명사 단위·숫자·기호처럼 분석기마다 관행이 갈리는 곳은 양쪽에서 똑같이 지웁니다. 차이는 Kiwi CoNg 대비이고, 괄호는 95% 구간입니다.
| 분석기 | MP 2025 문어 F1 | MP 2025 구어 F1 | 신문 1990~2025 420문장 F1 | 모호성 kiwi510 정확도 | 속도 KB/s | 메모리 MB |
|---|---|---|---|---|---|---|
| madi 기본 | 0.9774+0.32p [+0.24, +0.39] | 0.9640+0.53p [+0.44, +0.64] | 0.9772 | 0.7471 | 284 | 469 |
| madi 정밀 | 0.9784+0.42p [+0.34, +0.50] | 0.9656+0.69p [+0.59, +0.80] | 0.9786 | 0.8137 | 26 | 525 |
| madi n-gram 만 | 0.9751+0.09p | 0.9611+0.25p | 0.9746 | 0.7196 | 398 | 338 |
| Kiwi CoNg | 0.9742 | 0.9586 | 0.9737 | 0.8275 | 268 | 580 |
| Kiwi CoNg-global | 0.9751+0.09p | 0.9603+0.16p | 0.9719 | 0.8667 | 107 | 600 |
| Khaiii | 0.9554 | 0.9189 | 0.9386 | 0.5588 | 290 | 30 |
| mecab-ko | 0.9157 | 0.9053 | 0.9182 | 0.5549 | 2,592 | 76 |
| Komoran | 0.9032 | 0.8571 | 0.8733 | 0.4765 | 274 | 713 |
| Kkma | 0.8451 | 0.7929 | 0.8401 | 0.5275 | 18 | 900 |
- 기본 모드는 모호성 벤치마크 kiwi510 에서 Kiwi 보다 낮습니다(0.7471 대 0.8275, p 0.0002). 정밀 모드는 같은 수준입니다(차이 유의하지 않음). 일반 문장의 형태소 F1 은 기본 모드도 앞섭니다.
- 신문 420문장에서 madi 기본과 Kiwi CoNg 의 차(+0.35p)는 유의하지 않습니다. 정밀 모드의 차(+0.49p)는 유의합니다.
- 속도·메모리: 노트북 1스레드, Python 바인딩, 분석 뒤 최대 RSS. Khaiii 는 같은 노트북의 WSL 에서 쟀습니다. JVM 분석기의 메모리는 JVM 힙을 포함합니다. Hannanum·Okt 는 세종 태그로 옮길 수 없어 표에서 뺐습니다.
- 공개판은 위 측정 설정에 전후향 가지치기(τ 11)를 더한 것입니다. 측정 셋 1만 7천 문장 중 5문장만 출력이 바뀌고, LM 질의가 44% 줄어 CLI 에서 약 17% 빨라집니다.
모델·이용 조건
| 무엇 | 어디 | 조건 |
|---|---|---|
| 분석기 코드 (madi-core · madi-lm · madi · madi-cli 등) | crates.io, PyPI madipy | MIT 또는 Apache-2.0 |
| 모델·사전 파일, WASM 경량 모델 | GitHub Release models-kword5 | CC BY-SA 2.0 KR |
| 맞춤법 검사기 (LSP · VS Code 확장) | 실행 파일로만 | 무료 이용 조건 |
| 학습·평가 도구, 말뭉치 원문 | 제공하지 않음 | — |
모델·사전 파일은 CC BY-SA 2.0 KR 입니다. 국립국어원 모두의 말뭉치(형태 분석 말뭉치 2018~2020, 형태 분석 말뭉치 2025, 어휘 의미 분석 말뭉치 2020)와 우리말샘을 활용하였습니다(국립국어원 공개 승인 2026-10-17). 신문 기사 원문으로 자기 라벨 학습을 했습니다. 모델은 말뭉치 원문을 담거나 복원할 수 없는 통계·가중치입니다. 사전은 mecab-ko-dic(Apache-2.0)을 바탕으로 합니다.
학습 입력 목록은 MODEL-PROVENANCE.md, 출처 표시 예는 Release 의 LICENSE-MODELS.txt 에 있습니다.