Skip to main content

Crate madi

Crate madi 

Source
Expand description

§madi(마디) — 순수 Rust 한국어 형태소 분석기

이 크레이트는 madi 의 라이브러리 진입점입니다. 사전과 언어 모델을 열어 Engine 을 만들고, 스레드마다 EngineWorker 를 하나씩 받아 문장을 분석합니다. 명령줄 도구는 madi-cli, Python 패키지는 madipy(import madi), 둘 다 이 크레이트 위에 얹혀 있습니다.

§모델 파일

사전·언어 모델은 크레이트에 들어 있지 않습니다. 위 저장소의 Release models-kword5 에서 받아 풉니다 (CC BY-SA 2.0 KR).

파일무엇필요한 때
madi.dict사전(어휘·활용형·복합어·연접표)항상
knlm.binn-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_sentenceVec<Token> (위치는 그 문장 안)
여러 줄을 문장으로 나누고 각 문장 분석EngineWorker::sentencesVec<SentSpan> (입력 전체 기준 위치·어절 번호)
위 결과를 한 줄로EngineWorker::tokenizeVec<Morph>
문장 경계만EngineWorker::split_sentencesVec<String>
상위 n 개 후보와 점수EngineWorker::analyze_nbestVec<(f32, Vec<Token>)>
특정 구간을 정해진 형태소로EngineWorker::analyze_pretokenized(Vec<Token>, Vec<bool>)
기사·문서를 말뭉치 만들 듯 처리(정제·보일러플레이트 제거)EngineWorker::analyze_docVec<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.
EngineConfig
Engine 을 만드는 설정. EngineConfig::new 로 사전 경로만 주고 나머지는 구조체 갱신 문법으로 바꾼다.
EngineWorker
스레드 하나의 분석 작업 버퍼. Engine::worker 로 받는다.
Morph
위치가 붙은 형태소 — EngineWorker::sentences·EngineWorker::tokenize 의 결과 단위.
Options
분석 옵션·품사·토큰 — madi-core 의 것을 그대로 내보낸다. 분석·출력 옵션. Options::default() 가 공개판의 운영 설정이며 보통 그대로 쓴다.
PreciseOpt
정밀 모드 설정(τ 문턱·후보 수 등). EngineConfig::precise_opt.
Pretoken
미리 정한 구간 — EngineWorker::analyze_pretokenized 의 입력 (Kiwi 의 pretokenized 에 해당).
SentSpan
문장 하나의 구간과 형태소 — 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)은 어간 + “다”(들어가 → 들어가다), 그 밖은 형태 그대로.