publica-lightgbm-gliclass

Autor: Roberto Vasconcelos Novaes — LabP² – Laboratório de Tecnologias Públicas para o Setor Público, Faculdade de Direito, Universidade Federal de Minas Gerais.

English summary. This package labels each block of a scholarly article PDF (as read by Docling) with one of 35 roles (title, authors, affiliation, abstract, keywords, section heading, paragraph, reference, table, footnote, funding statement…), so the article can be assembled into JATS XML (SciELO Publishing Schema) by PUBLICA LABP². It is a pair that only works together: (1) a GLiClass text classifier fine-tuned from knowledgator/gliclass-multilang-mini (Apache-2.0), which reads each block and outputs 35 probabilities; (2) a LightGBM model that decides the role from neutral layout features plus those 35 probabilities (stacking). Trained on 3,459 open-access articles from SciELO, Redalyc, PMC and PLOS, mostly in Portuguese, Spanish and English. On a held-out test set of 664 articles the method scores 59.1% on the average of 11 XML fields, against 53.1% for LightGBM alone (those figures are from models trained on the training split only; the published package is trained on all collections and has no held-out measurement). Weights are stored in half precision (fp16) and run in fp32 on CPU: about 23 s per article with 8 threads.

O que é

O pacote do sugestor lightgbm-gliclass do PUBLICA LABP² (PDF de manuscrito → XML JATS no perfil SciELO PS). Ele dá a cada bloco que o Docling lê de um PDF um de 35 papéis (título, autores, afiliação, resumo, palavras-chave, seção, parágrafo, referência, tabela, nota, financiamento…). Na aplicação é só uma sugestão: o editor confere e corrige na tela de marcação.

É um par, e as duas partes só valem juntas:

arquivo conteúdo
model.safetensors, config.json, tokenizer.json, tokenizer_config.json o GLiClass ajustado (pesos em meia precisão, fp16)
docling-bruto.gliclass.txt.gz, docling-bruto.gliclass.json o LightGBM treinado com as pistas neutras + as 35 probabilidades do GLiClass
manifesto.json versão, SHA-256 e tamanho de cada arquivo, precisão dos pesos, receita, data e o hash do estado do bloco
  • GLiClass (modelo de linguagem ajustado): lê o texto de cada bloco e dá um palpite, uma probabilidade para cada um dos 35 papéis. Não decide.
  • LightGBM: decide o papel, combinando 115 pistas neutras de forma (posição, tamanho, classe do Docling, vizinhos…) com os 35 palpites. Na literatura isso é empilhamento (stacking).

Versão deste pacote: dc22ab16315f-58fbfba02d56, de 04/10/2026 (SHA-256 do manifesto.json: df466178d258fd2e4a8731861dafc374b164bcc1054586f1c78f1cc98a616761; pesos: dc22ab16315f…; LightGBM: 24d50eff32a1…; 564 MB no total).

Modelo de base e licença

  • Base: knowledgator/gliclass-multilang-mini, revisão 0bd888b6c3ef9fca5f0a9d407bddfbbc7623486b, Apache-2.0 (campo license do cartão do modelo; conferido em 04/10/2026 pela API do Hugging Face). O codificador é o microsoft/mdeberta-v3-base (MIT).
  • Biblioteca: gliclass 0.1.20; LightGBM (MIT).
  • Licença deste pacote: Apache-2.0, a mesma da base.

Dados de treino e licenças

Artigos de acesso aberto, com o PDF e o XML JATS oficial de cada um. O gabarito de cada bloco vem do alinhamento automático entre o texto do bloco e o XML oficial (rotulagem 4 do projeto); só os blocos de rótulo confiável (confiança ≥ 0,7) ensinam. O modelo do produto é treinado com todas as coleções: 3.459 artigos de 552 revistas, 770.426 blocos.

Licença declarada no XML oficial de cada artigo (<license>), nos 3.483 artigos do corte (contagem de 04/10/2026):

coleção artigos CC BY CC BY-NC CC BY-NC-SA CC BY-NC-ND CC0 sem <license>
SciELO (geral) 1.000 918 69 0 13 0 0
SciELO (humanas) 500 405 95 0 0 0 0
PMC (Open Access) 500 499 0 0 0 1 0
PLOS 500 481 0 0 0 19 0
Redalyc 494 35 0 440 0 0 19
Redalyc (diversificado) 489 322 62 75 15 0 15
total 3.483 2.660 226 515 28 20 34

O pacote não contém texto dos artigos: só os pesos do GLiClass, as árvores do LightGBM e metadados do treino. Ainda assim, 769 artigos (22%) têm licença com restrição (não comercial, sem derivados ou compartilha igual) e 34 não trazem licença no XML. O pacote foi treinado com todos os 3.483 artigos (decisão do responsável, 04/10/2026); quem reutilizar os pesos deve considerar essas licenças de origem.

Receita

  • Estado do bloco (o texto que o GLiClass lê; só o que o extrator entrega, nenhuma regra nossa): Layout label: <classe do Docling>. Page <p> of <n>. [Heading level <k>.], a classe e os primeiros 80 caracteres do bloco anterior e do seguinte, e Text: <texto> (até 1.500 caracteres); a entrada (35 rótulos + estado) é cortada em 640 tokens.
  • Ajuste fino do GLiClass: word_embeddings congelado; lote 16 com acumulação 2; bf16; taxa 1e-5 no codificador e 3e-5 no resto; decaimento 0,01; aquecimento de 5%; 1 época sobre uma amostra de 60 mil blocos (cota por papel proporcional à raiz da frequência); semente 20261002; 35 rótulos em inglês sempre presentes; problema multi-rótulo.
  • Ajuste cruzado: os artigos são divididos em 3 partes por revista; três GLiClass, cada um treinado em duas partes, dão o palpite da terceira. O LightGBM aprende com esses palpites "fora da parte" (de um modelo que não viu o bloco). O GLiClass deste pacote é o quarto, treinado com tudo.
  • LightGBM: os parâmetros do classificador do projeto, parada antecipada numa fatia de revistas, treino determinístico; 80 rodadas.
  • Pontuação: a sigmoide de cada um dos 35 papéis (pipeline multi-rótulo do gliclass).
  • Versões do treino: gliclass 0.1.20, torch 2.14.1, transformers 5.18.0, accelerate 1.15.0; GPU RTX 4060 (8 GB); Docling 2.132 na extração.

Resultados

Medidos com modelos treinados só com a partição de treino (1.695 artigos), na régua comum do projeto: média de 11 campos do XML gerado contra o XML oficial (título, autores, afiliações, títulos traduzidos, resumos, texto do resumo, palavras-chave, seções, referências, tabelas, notas), falha de conversão contando como erro.

validação (1.118 artigos) teste (664 artigos)
LightGBM puro 49,5% 53,1%
GLiClass sozinho 49,0% 51,0%
LightGBM + GLiClass 57,7% 59,1%
teto (papéis do gabarito) 64,5% 67,4%

Por bloco, no teste (146.621 blocos de rótulo confiável): acerto de 94,3% e macro-F1 de 0,768 (LightGBM puro: 92,4% e 0,669).

Ressalva: o pacote publicado é treinado com todas as coleções, inclusive a validação e o teste, para a aplicação aproveitar todos os artigos. Ele não tem medida em artigos que não viu; os números acima são do mesmo método com menos dados, não deste arquivo.

Tempo e memória

  • GPU (RTX 4060, bf16, lote 32): ~143 blocos por segundo (um artigo em 2 a 3 s).
  • CPU (Ryzen 7 7800X3D, 8 threads, um bloco por lote, pesos fp16 rodando em fp32; 12 artigos da validação de 144 a 360 blocos): mediana de 23,6 s por artigo (máximo 43,4 s; 9,95 blocos por segundo), pico de 2,6 GB de memória no processo. Com 4 threads, cerca do dobro do tempo; 16 threads (núcleos lógicos) são mais lentas que 8.
  • Meia precisão: o arquivo cai de 1.082 MB para 541 MB. Nos 3.042 blocos dos 12 artigos, os pesos fp16 na CPU dão o mesmo papel de maior probabilidade que os fp32 na GPU em 99,67% dos blocos (10 diferentes), e o mesmo papel final do LightGBM em 99,64% (11 diferentes). Contra as pontuações "fora da parte" com que o LightGBM foi treinado (2.652 blocos de rótulo confiável), o papel final coincide em 98,98%.
  • Quantização int8 dinâmica foi descartada: muda o papel de 712 de 3.042 blocos.

Limitações

  • Só vale para blocos do Docling (extrator docling-bruto, Docling 2.132): o estado do bloco usa as classes de layout dele.
  • O gabarito é automático (alinhamento com o XML oficial), com ruído.
  • Autores, afiliações e notas continuam difíceis: parte do erro está na extração e na montagem do XML, não na classificação.
  • O corpus é de revistas do SciELO, do Redalyc, do PMC e da PLOS; PDFs de outros leiautes (preprints, manuscritos sem diagramação) não foram medidos.
  • É uma sugestão para um editor humano conferir, não uma decisão.

Como instalar

No PUBLICA LABP² (com o extra gliclass do backend instalado):

make gliclass-modelo                      # baixa deste repositório, na revisão fixada no código
make gliclass-modelo ORIGEM=/caminho      # ou de um diretório ou .tar local

O comando confere o SHA-256 de cada arquivo com o manifesto.json, e o manifesto com o vínculo versionado no código (backend/apps/jats/sugestor/docling-bruto.gliclass.vinculo.json); pacote de versão diferente da que o código espera é recusado. Nada é baixado durante a conversão.

Só o GLiClass, fora da aplicação

O GLiClass pode ser usado sozinho para classificar o texto de um bloco (pip install gliclass). O LightGBM do par depende das 115 pistas que a aplicação calcula a partir do Docling (a ordem das 150 colunas está em atributos, no .json), e por isso é pouco útil fora dela.

from gliclass import GLiClassModel, ZeroShotClassificationPipeline
from transformers import AutoTokenizer

REPO = "labp2/publica-lightgbm-gliclass"  # ou a pasta local do pacote
tokenizer = AutoTokenizer.from_pretrained(REPO)
model = GLiClassModel.from_pretrained(REPO).float().eval()  # pesos em fp16; na CPU rodam em fp32
pipe = ZeroShotClassificationPipeline(
    model, tokenizer, classification_type="multi-label", device="cpu",
    max_classes=35, max_length=640, progress_bar=False,
)

# Os 35 rótulos, em inglês, na ordem usada no treino.
LABELS = [
    "article title", "subtitle", "translated title", "authors", "affiliation",
    "author note", "email or orcid", "correspondence", "abstract", "keywords",
    "dates", "license", "epigraph", "section heading", "paragraph", "list item",
    "block quote", "table caption", "table", "figure caption", "figure",
    "table or figure source", "footnote", "acknowledgments",
    "references heading", "reference", "page furniture", "doi", "funding",
    "author biography", "equation", "conflict of interest", "handling editor",
    "data availability", "author contributions",
]

# O "estado do bloco": a classe que o Docling deu, a página, os vizinhos e o texto.
bloco = (
    "Layout label: text. Page 12 of 14.\n"
    "Previous block (section_header): Financiamento\n"
    "Next block (section_header): Referências\n"
    "Text: Esta pesquisa foi financiada pela FAPEMIG (processo APQ-00000-00) e pelo CNPq."
)
resultado = pipe(bloco, LABELS, threshold=0.0)[0]
for item in sorted(resultado, key=lambda r: -r["score"])[:3]:
    print(f'{item["label"]}: {item["score"]:.2f}')

Saída (pacote dc22ab16315f-58fbfba02d56, na CPU): funding: 0.97, page furniture: 0.00, footnote: 0.00. As pontuações são independentes (uma sigmoide por rótulo), não somam 1.

Modelos relacionados

  • labp2/publica-lightgbm: o LightGBM puro (só as pistas neutras, sem o GLiClass), o sugestor padrão da aplicação e o modelo de comparação dos experimentos.

Contato

Roberto Vasconcelos Novaes — rnovaes@ufmg.br

Citação

NOVAES, Roberto Vasconcelos. Publica LabP² — LightGBM + GLiClass para marcação JATS de artigos científicos (modelo). LabP², Faculdade de Direito, UFMG, 2026. Disponível em: https://huggingface.co/labp2/publica-lightgbm-gliclass

O artigo que descreve o método será referenciado aqui quando for publicado.

Downloads last month
17
Safetensors
Model size
0.3B params
Tensor type
F16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for labp2/publica-lightgbm-gliclass

Finetuned
(1)
this model