GLiNER: 로컬 판단과 엔터티 추출

개발 프리뷰. 가중치는 Hugging Face에 공개되었습니다. Swift 모듈은 리뷰 중이며 아직 speech-swift 릴리스에 포함되지 않았습니다.

GLiNER 모듈은 MLX Swift에서 GLiNER2.5-Decide를 실행합니다. 텍스트와 허용할 레이블 목록을 주면 분류 점수를 얻을 수 있고, 사람이나 시간 같은 엔터티 스팬도 요청할 수 있습니다.

작동 방식

DeBERTa 인코더가 텍스트와 스키마를 함께 읽습니다. 분류 헤드는 레이블에 점수를 매기고, 엔터티 헤드는 원문에서 스팬을 찾습니다. 런타임은 JSON 응답을 토큰 단위로 생성하지 않습니다.

import GLiNER
let model = try await GLiNER.fromPretrained()
let choices = try model.classify(
    "Remind me to call Dad at six PM.",
    labels: ["create_reminder", "send_message", "other"]
)
let spans = try model.extractEntities(
    "Remind me to call Dad at six PM.",
    labels: ["person", "time"]
)

가중치

고정된 업스트림 리비전 7ee5da4c의 MLX 변환 세 가지가 Hugging Face에 공개되어 있습니다. 런타임은 처음 사용할 때 선택한 버전을 내려받고 이후에는 로컬 캐시를 재사용합니다. Python은 필요하지 않습니다.

버전저장소가중치라우팅추출최대 메모리
int8 (기본값)aufklarer/GLiNER2.5-Decide-340M-MLX-8bit567 MB7.6 ms8.9 ms0.85 GB
fp16aufklarer/GLiNER2.5-Decide-340M-MLX-fp16973 MB8.8 ms10.0 ms1.58 GB
fp32aufklarer/GLiNER2.5-Decide-340M-MLX1.95 GB11.1 ms12.6 ms2.55 GB

Apple M5 Pro, 다른 부하 없음: 토큰화를 포함한 전체 요청의 중앙값과 프로세스 최대 메모리. 세 버전 모두 24개 참조 사례에서 업스트림 PyTorch 모델과 같은 레이블, 스팬, 오프셋을 반환하며 신뢰도 차이는 0.006 이내입니다.

명령줄

speech CLI는 두 작업을 speech gliner classify와 speech gliner extract로 제공합니다. 레이블은 쉼표로 구분해 전달하고 --description label=text는 여러 번 지정할 수 있습니다. 텍스트를 생략하면 stdin에서 읽습니다. --variant로 int8(기본값), fp16, fp32 중 하나를 고르고, --model-dir는 내려받는 대신 로컬 번들을 불러옵니다. 잘못된 인수는 모델을 불러오기 전에 거부됩니다. --json을 쓰면 모든 레이블의 확률 또는 UTF-16 오프셋이 있는 스팬과 함께 로딩 및 추론 시간을 출력합니다.

swift build -c release --product speech --disable-sandbox
scripts/build_mlx_metallib.sh release
.build/release/speech gliner classify "Remind me to call Dad at six PM." \
  --labels create_reminder,send_message,set_timer,other
.build/release/speech gliner extract "Remind me to call Dad at six PM." \
  --labels person,time --json

에이전트용 모델 카드는 정확한 API, 출력 필드, 검증된 결과를 정리한 Markdown 파일입니다.

작은 명령 세트에서의 정확도

직접 작성한 라우팅 예시 16개 중 12개, 추출 예시 8개 중 7개가 기대와 일치했습니다. Swift 포트는 24개 참조 사례에서 업스트림 PyTorch 모델을 재현합니다. 토큰 ID, 레이블, 스팬이 같고 점수 차이는 0.001 이내입니다. 이 작은 세트는 동작과 재현성을 확인하기 위한 것이며 폭넓은 정확도 벤치마크가 아닙니다.

범위와 제한

정밀도와 메모리

FP16은 가중치 저장 용량을 절반인 973MB로 줄입니다. INT8은 인코더 행렬과 토큰 임베딩을 64개 단위로 8비트 양자화하고, 헤드·정규화·활성화는 FP16으로 유지해 파일이 567MB입니다. 런타임은 INT8 행렬을 압축된 상태로 두고 요청에 필요한 임베딩 행만 디코딩합니다.

인코더의 상대 위치 투영은 가중치에만 의존하므로 요청마다가 아니라 로딩할 때 한 번만 계산합니다. 선택 옵션인 GLiNER.load(from:evaluateLayers:) 모드는 인코더 레이어를 하나씩 계산해 최대 할당량을 낮춥니다.

출처와 저작자 표시