Expand description
§madi(마디) — 순수 Rust 한국어 형태소 분석기
이 크레이트는 madi 의 라이브러리 진입점입니다. 사전과 언어 모델을 열어 Engine 을 만들고,
스레드마다 EngineWorker 를 하나씩 받아 문장을 분석합니다. 명령줄 도구는 madi-cli,
Python 패키지는 madipy(import madi), 둘 다 이 크레이트 위에 얹혀 있습니다.
- 품사는 세종 태그 체계(
Tag: NNG·VV·JKS …)이고, 분석 관행은 국립국어원 모두의 말뭉치 형태 분석 지침을 따릅니다. - 형태소 분석을 이용한 문장 분리(종결 부호가 없어도 종결 어미 뒤에서 끊음)를 함께 제공합니다.
- 소개 페이지 https://p14jeffwest.github.io/madi-release/, 모델·이용 조건 https://github.com/p14jeffwest/madi-release.
§모델 파일
사전·언어 모델은 크레이트에 들어 있지 않습니다. 위 저장소의 Release models-kword5 에서 받아 풉니다
(CC BY-SA 2.0 KR).
| 파일 | 무엇 | 필요한 때 |
|---|---|---|
madi.dict | 사전(어휘·활용형·복합어·연접표) | 항상 |
knlm.bin | n-gram 언어 모델(KnLM) | 권장 — 없으면 ko-dic 연접표만으로 분석 |
model.nlm | 신경망 언어 모델(NLM) | 기본 모드(feature nlm, 기본 켬) |
precise.tlm | 정밀 모드 교사(작은 트랜스포머) | precise 를 줄 때만 |
§빠른 시작
use madi::{Engine, EngineConfig, NLM_MIX_WEIGHTS};
// 기본 모드(사전 + KnLM + NLM). Python 패키지·CLI 의 기본값과 같다.
let cfg = EngineConfig {
knlm: Some("models/knlm.bin".into()),
nlm: Some("models/model.nlm".into()),
lm_weight: NLM_MIX_WEIGHTS.0,
nlm_weight: NLM_MIX_WEIGHTS.1,
skip: madi::Skip::Off, // 문서 정제·문장 버리기 없이 (라이브러리 용도)
min_len: 0,
..EngineConfig::new("models/madi.dict")
};
let engine = Engine::load(&cfg)?; // 1초 안팎, 한 번만 만들어 공유
println!("{}", engine.version()); // 0.2.1+decdb.r3p.f11.k838c.n15e6.s-
let mut w = engine.worker(); // 스레드마다 하나
for t in w.analyze_sentence("아버지가 방에 들어가신다.") {
print!("{}/{} ", t.form, t.tag.code()); // 아버지/NNG 가/JKS 방/NNG 에/JKB 들어가/VV 시/EP ㄴ다/EF ./SF
}§어느 함수를 쓰나
| 하고 싶은 것 | 함수 | 돌려주는 것 |
|---|---|---|
| 문장 하나 분석 | EngineWorker::analyze_sentence | Vec<Token> (위치는 그 문장 안) |
| 여러 줄을 문장으로 나누고 각 문장 분석 | EngineWorker::sentences | Vec<SentSpan> (입력 전체 기준 위치·어절 번호) |
| 위 결과를 한 줄로 | EngineWorker::tokenize | Vec<Morph> |
| 문장 경계만 | EngineWorker::split_sentences | Vec<String> |
| 상위 n 개 후보와 점수 | EngineWorker::analyze_nbest | Vec<(f32, Vec<Token>)> |
| 특정 구간을 정해진 형태소로 | EngineWorker::analyze_pretokenized | (Vec<Token>, Vec<bool>) |
| 기사·문서를 말뭉치 만들 듯 처리(정제·보일러플레이트 제거) | EngineWorker::analyze_doc | Vec<Sentence> |
| 사전에 없는 말 보태기 | Engine::add_user_word, Engine::load_user_dictionary, EngineConfig::user | — |
§모드
| 모드 | 설정 | 특징 |
|---|---|---|
| 기본 | knlm + nlm, 가중 NLM_MIX_WEIGHTS | 대부분의 용도 |
| 정밀 | 기본 + precise: Some("precise.tlm") | 애매한 어절을 교사가 다시 고름. 약 10배 느림 |
| 가벼운 | knlm 만(nlm: None, lm_weight: 1.0) | 메모리 약 130 MB 적음, 정확도 조금 낮음. default-features = false 로 빌드 가능 |
§스레드
Engine 은 Send + Sync 라 Arc 로 여러 스레드가 공유하고, 각 스레드는 Engine::worker 로
자기 작업 버퍼를 받습니다. 분석은 문장마다 독립이라 스레드 수와 관계없이 결과가 같습니다.
§위치와 어절
모든 위치는 글자(char) 단위 반열린 구간 [start, end) 입니다(바이트가 아님). 축약된 활용형은
여러 형태소가 같은 구간을 가리킵니다: “신다” → 시/EP(11..13) + ㄴ다/EF(11..13). Token::space_before
가 참이면 그 형태소가 새 어절의 시작입니다.
§판본 문자열
Engine::version 은 0.2.1+decdb.r3p.f11.k838c.n15e6.s-[.u…][.w…][.p…] 꼴로, 크레이트 판본 뒤에
사전·점수 가중 판·가지치기 문턱·KnLM·NLM·보일러플레이트 규칙의 해시가 붙습니다. 사용자 사전을 쓰면 .u,
기본값과 다른 가중·옵션이 있으면 .w, 정밀 모드면 .p 가 더 붙습니다. 두 실행의 판본 문자열이 같으면
같은 입력에 같은 출력을 냅니다.
Re-exports§
pub use madi_news as news;
Modules§
- split
- 형태소 분석 결과를 쓰는 문장 분리 규칙 (
EngineWorker::split_sentences·EngineWorker::sentences가 쓴다). 형태소 분석 결과를 쓰는 문장 분리 규칙.EngineWorker::split_sentences와EngineWorker::sentences가 이 모듈의split_line을 쓴다. - text
- 문서 전처리: 보일러플레이트 규칙, 규칙 기반 문장 분리(
text::split_sentences), 토큰 줄 형식. 문서 전처리: 보일러플레이트 규칙(SkipRules: 정제·문장 버리기), 규칙 기반 문장 분리(split_sentences), 토큰 줄 형식(format_tokens).madi corpus명령과Engine::analyze_doc이 같은 코드를 쓴다. 형태소 분석을 이용한 문장 분리는crate::split과EngineWorker::sentences에 있다.
Structs§
- DocResult
EngineWorker::analyze_doc_full의 결과: 남은 문장들과 버린 문장 수.- Engine
- 공유 분석기: 사전·언어 모델·옵션을 한 번 메모리에 올린 것.
Send + Sync. - Engine
Config Engine을 만드는 설정.EngineConfig::new로 사전 경로만 주고 나머지는 구조체 갱신 문법으로 바꾼다.- Engine
Worker - 스레드 하나의 분석 작업 버퍼.
Engine::worker로 받는다. - Morph
- 위치가 붙은 형태소 —
EngineWorker::sentences·EngineWorker::tokenize의 결과 단위. - Options
- 분석 옵션·품사·토큰 —
madi-core의 것을 그대로 내보낸다. 분석·출력 옵션.Options::default()가 공개판의 운영 설정이며 보통 그대로 쓴다. - Precise
Opt - 정밀 모드 설정(τ 문턱·후보 수 등).
EngineConfig::precise_opt. - Pretoken
- 미리 정한 구간 —
EngineWorker::analyze_pretokenized의 입력 (Kiwi 의pretokenized에 해당). - Sent
Span - 문장 하나의 구간과 형태소 —
EngineWorker::sentences의 결과 단위. - Sentence
EngineWorker::analyze_doc이 돌려주는 문장 하나: 정제된 문장 글과 그 형태소들. 토큰 위치는 이 문장 안 글자 위치다(입력 전체 기준이 필요하면EngineWorker::sentences).- Token
- 분석 옵션·품사·토큰 —
madi-core의 것을 그대로 내보낸다. 분석 결과 형태소 하나.
Enums§
- Skip
- 문서 정제·문장 버리기 규칙(보일러플레이트 규칙)을 어디서 가져올지.
EngineConfig::skip. - Tag
- 분석 옵션·품사·토큰 —
madi-core의 것을 그대로 내보낸다. 품사 태그. 세종 체계(NNG·VV·JKS·EF …)에 모두의 말뭉치·madi 확장을 더한 것. - TagStyle
- 분석 옵션·품사·토큰 —
madi-core의 것을 그대로 내보낸다. 품사 표시 방식 —Token::display와 CLI--tags가 쓴다.TagStyle::show로 문자열을 얻는다
Constants§
- NLM_
MIX_ WEIGHTS - 신경망 LM 을 함께 쓸 때의 운영 가중
(lm_weight, nlm_weight)= (0.7, 0.3). 기본 모드의EngineConfig::lm_weight·nlm_weight에 이 값을 넣는다. CLI 는--nlm만 주면 이 값을 쓴다.
Functions§
- format_
tokens - 토큰들을 한 줄 글로:
형태/코드 형태/코드 | 형태/코드 …(어절 경계는|).madi corpus --tokens출력의 둘째 열과 같은 형식. - hash_
bytes - 바이트열의 64비트 해시(FNV 식, 8바이트 단위). 판본 문자열을 만드는 데 쓴다.
h는 시작값(이어서 해시할 때 앞 결과). - hash_
file - 파일 내용의 64비트 해시(
hash_bytes와 같은 값을 1 MB 씩 읽어 가며). 사전·모델 파일의 판본 해시에 쓴다. - hash_
text - 텍스트의 64비트 해시. BOM 을 떼고 줄끝을 LF 로 맞춘 뒤 재므로 Windows 에서 CRLF 로 풀린 파일도 같은 값이 난다.
사용자 사전·규칙 파일의 판본 해시(
.u·.s)에 쓴다. - hash_
words hash_file과 같은 값을 메모리 버퍼에서 낸다 —words는 8바이트 단위로 담은 내용,len은 실제 바이트 수.Engine::from_memory(WASM 등 파일이 없는 환경) 가 쓴다. 리틀 엔디언 가정(x86·wasm32).- knob_
diff - 설정 가운데 기본값과 다른 칸을
이름=값목록으로 — 판본 문자열의.w해시가 무엇에서 왔는지 확인할 때 (madi version --knobs가 이것을 찍는다). 비어 있으면 기본 설정이다. - lemma
- 원형(lemma): 용언(VV·VA·VX·VCP·VCN)은 어간 + “다”(들어가 → 들어가다), 그 밖은 형태 그대로.