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ão0bd888b6c3ef9fca5f0a9d407bddfbbc7623486b, Apache-2.0 (campolicensedo cartão do modelo; conferido em 04/10/2026 pela API do Hugging Face). O codificador é omicrosoft/mdeberta-v3-base(MIT). - Biblioteca:
gliclass0.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, eText: <texto>(até 1.500 caracteres); a entrada (35 rótulos + estado) é cortada em 640 tokens. - Ajuste fino do GLiClass:
word_embeddingscongelado; 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
Model tree for labp2/publica-lightgbm-gliclass
Base model
knowledgator/gliclass-multilang-mini