GLiNER: decisões e extração de entidades localmente

Prévia de desenvolvimento. Os pesos estão publicados no Hugging Face; o módulo Swift está em revisão e ainda não faz parte de uma versão do speech-swift.

O módulo GLiNER executa o GLiNER2.5-Decide em MLX Swift. Passe um texto e uma lista de rótulos permitidos para obter pontuações de classificação, ou peça trechos de entidades como uma pessoa e um horário.

Como funciona

Um codificador DeBERTa lê o texto e o esquema juntos. As cabeças de classificação pontuam seus rótulos. As cabeças de entidades identificam trechos da frase original. O runtime não gera uma resposta JSON token por token.

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"]
)

Pesos

Três conversões MLX da revisão fixada 7ee5da4c estão publicadas no Hugging Face. O runtime baixa a variante escolhida no primeiro uso e depois reutiliza o cache local; o Python não é usado.

VarianteRepositórioPesosRoteamentoExtraçãoMemória máxima
int8 (padrão)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, máquina ociosa: mediana de uma requisição completa com tokenização, e memória máxima do processo. As três variantes retornam os mesmos rótulos, trechos e offsets que o modelo PyTorch original em 24 casos de referência, com diferenças de confiança abaixo de 0,006.

Linha de comando

A CLI speech oferece as duas tarefas como speech gliner classify e speech gliner extract. Os rótulos são passados separados por vírgula e --description label=text pode ser repetido. Sem texto, a entrada é lida do stdin. --variant escolhe int8 (padrão), fp16 ou fp32, e --model-dir carrega um pacote local em vez de baixar. Argumentos inválidos são rejeitados antes de o modelo carregar. Com --json, a saída inclui a probabilidade de cada rótulo, ou trechos com offsets UTF-16, além dos tempos de carga e inferência.

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

O cartão do modelo para agentes é um arquivo Markdown com a API exata, os campos de saída e os resultados verificados.

Precisão em um pequeno conjunto de comandos

Dos dezesseis exemplos de roteamento escritos à mão, 12 corresponderam ao esperado; dos oito exemplos de extração, 7. O port em Swift reproduz o modelo PyTorch original em 24 casos de referência: mesmos IDs de token, rótulos e trechos, com pontuações dentro de 0,001. Esses conjuntos pequenos verificam comportamento e fidelidade; não são um benchmark amplo de precisão.

Escopo e limitações

Precisão e memória

O FP16 reduz pela metade o armazenamento dos pesos, para 973 MB. O INT8 quantiza as matrizes do codificador e os embeddings de tokens em 8 bits, em grupos de 64, com cabeças, normalização e ativações em FP16, resultando num arquivo de 567 MB. O runtime mantém as matrizes INT8 compactadas e decodifica apenas as linhas de embedding usadas por cada requisição.

As projeções de posição relativa do codificador dependem só dos pesos, então são calculadas uma vez no carregamento, e não a cada requisição. O modo opcional GLiNER.load(from:evaluateLayers:) materializa as camadas do codificador uma a uma para reduzir o pico de alocações.

Fontes e atribuição