Interface reproduzível para o PortNOIE, sistema de Open Information Extraction (Open IE) em português desenvolvido no doutorado de Bruno Souza Cabral com Marlo Vieira dos Santos e Souza e Daniela Barreiro Claro.
Esta distribuição oferece dois caminhos de inferência:
modern(padrão): migração experimental do núcleo neural em PyTorch, sem AllenNLP, Flair nem os dois arquivos externos de language model;legacy: implementação AllenNLP histórica, preservada somente para comparações de compatibilidade.
Ambos usam o checkpoint histórico de bratao/PortNOIE no Hugging Face,
baixado automaticamente e mantido em cache na primeira extração. A API normaliza a saída em triplas
ARG0, V e ARG1 e remove pontuação marginal dos três campos.
O wheel instalado sem extras contém somente a API leve e as verificações de integridade; sozinho ele não executa inferência. Use o extra
modernno comando de instalação da release abaixo para habilitar o backend padrão.
Não é o melhor BERT da tese. O
model.thde 74.832.847 bytes é um artefato histórico/de referência: BiLSTM de uma camada, hidden size 384 e representações Flair Diário bidirecionais de 1024. O melhor modelo BERT descrito na tese será distribuído separadamente quando sua validação terminar.
O backend moderno reconstrói em PyTorch o grafo serializado no checkpoint. As
14 matrizes das duas LMs Flair presentes em model.th foram comparadas com os
assets históricos: 14/14 eram idênticas com torch.equal. O checkpoint não
guarda o dicionário de 287 caracteres; por isso a distribuição inclui o sidecar
mínimo modern_data/flair_metadata.json, com proveniência e checksums dos
arquivos dos quais ele foi derivado. Seu próprio SHA-256 é verificado antes do
carregamento.
O caminho moderno usa torch.load(..., weights_only=True) e não abre
model_params.pkl. Por segurança, ele exige Torch 2.10 ou mais novo; versões
anteriores são bloqueadas por GHSA-63cw-57p8-fm3p.
Ele executou uma frase anotada e também texto bruto com o modelo spaCy real, produzindo:
Maria | escreveu | um livro
Isso demonstra execução reproduzível sem AllenNLP/Flair em runtime, mas não
prova equivalência ao legado. Ainda faltam comparação de logits e avaliação
em corpus entre os dois pipelines. Até lá, o nome retornado pela API é
PortNOIE-modern-experimental.
O pacote declara suporte a Python 3.10–3.13. Para o backend padrão, recomenda-se Python 3.11 ou mais novo:
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install --upgrade pip
python -m pip install "portnoie[modern]"
portnoie download # opcional: antecipar o download do checkpoint
portnoie doctor --checkpoint-onlyO wheel e o sdist não contêm os pesos. Não é necessário fornecer caminho de
modelo: a primeira extração baixa o checkpoint de cerca de 75 MB para o cache
Hugging Face, na revisão fixada na biblioteca, e verifica os hashes oficiais.
PortNOIE() e a importação do pacote não fazem downloads.
Para texto bruto, se pt_core_news_lg estiver ausente, auto_download=True
(padrão) também instala a wheel oficial pt_core_news_lg==3.8.0, de
568.207.147 bytes, via pip ou uv no mesmo Python que executa PortNOIE.
A URL contém o SHA-256 fixado, verificado pelo instalador. Essa primeira chamada
pode demorar e precisa de pip no ambiente ou de uv no PATH.
Em produção offline/controlada, execute portnoie download e instale previamente
a wheel spaCy fixada por SHA-256.
Depois use PortNOIE(local_files_only=True), PortNOIE(auto_download=False) ou
portnoie extract --local-files-only; todas essas opções impedem os downloads
automáticos tanto do checkpoint quanto do modelo spaCy.
Integrações que já possuem tokens, POS e dependências podem usar
extract_annotated e não precisam do modelo spaCy.
from portnoie import PortNOIE
extractor = PortNOIE() # backend="modern"
result = extractor.extract("Maria escreveu um livro.")
for triple in result.triples:
print(triple.as_dict())
# {'ARG0': 'Maria', 'V': 'escreveu', 'ARG1': 'um livro'}O objeto carrega os pesos e o pipeline spaCy de forma preguiçosa e os reutiliza
nas chamadas seguintes. result.raw preserva tokens, anotações, tags BIO e o
identificador explícito do backend. Por padrão, frames incompletos são
descartados; use PortNOIE(strict=False) para mantê-los.
Para preparar o cache sem executar inferência:
from portnoie import download_model
download_model() # baixa só o checkpoint oficial e verifica seus hashes
extractor = PortNOIE(local_files_only=True) # requer spaCy pré-instalado para texto brutocache_dir é opcional; por padrão vale o cache padrão do Hugging Face, configurável
por HF_HOME. revision permite selecionar outra revisão, mas não substitui os
hashes oficiais ancorados no pacote.
Para anotações já calculadas:
result = extractor.extract_annotated(
tokens=["Maria", "escreveu", "um", "livro", "."],
pos_tags=["PROPN", "VERB", "DET", "NOUN", "PUNCT"],
dependencies=["nsubj", "ROOT", "det", "obj", "punct"],
)Como no leitor histórico, cada grupo contíguo de tokens VERB/AUX gera uma
variação de indicador verbal. Labels de dependência desconhecidos usam o label
de fallback dep do vocabulário preservado. Predicados multiword e frames com
predicados sobrepostos são consolidados pelo mesmo algoritmo do preditor
histórico. Dígitos viram 0 antes das LMs de caracteres, enquanto o word shape
continua usando o token original.
portnoie download
portnoie doctor
portnoie extract "Maria escreveu um livro."
echo "Maria escreveu um livro." | portnoie extract --rawportnoie doctor não carrega a rede neural nem acessa a rede para baixar arquivos. Ele verifica
faixa de Python, hashes oficiais do checkpoint ancorados no pacote, sidecar,
versão segura de Torch, spaCy e pt_core_news_lg. O relatório distingue:
modern.annotated_ready: grafo pronto para anotações fornecidas;modern.raw_text_ready: também possui spaCy ept_core_news_lg;modern.raw_text_auto_download_available: pode instalar o modelo na primeira extração;legacy.ready: ambiente histórico e assets externos completos.
Use portnoie doctor --checkpoint-only para validar apenas o checkpoint local ou
em cache. Em uma instalação nova do wheel, o resultado esperado antes do primeiro
download é checkpoint.status="not-cached", com código de saída 1. Execute
portnoie download antes de repetir o diagnóstico. O comando completo também
retorna status diferente de zero quando o backend selecionado não está pronto.
Um model_dir customizado é comparado aos hashes oficiais por padrão; o
manifesto que estiver dentro dele não redefine essa raiz de confiança. Somente
artefatos deliberadamente diferentes podem usar trust_custom_model=True. Esse
opt-in confia no manifesto customizado para consistência, não para autenticidade,
e é obrigatório ao pular integridade antes de carregar o pickle legado.
O legado é explícito e limitado a Python 3.10 por causa de AllenNLP 2.10/Torch 1.12:
Não use em produção. Essa pilha está fora de suporte e contém dependências com vulnerabilidades conhecidas. Execute-a somente em ambiente descartável, isolado e offline, com os artefatos oficiais previamente baixados/verificados e sem dados não confiáveis.
python3.10 -m pip install -e ".[legacy]"
portnoie download
python3.10 -m spacy download pt_core_news_lg
portnoie doctor --backend legacy
portnoie extract --backend legacy "Maria escreveu um livro."Os extras modern e legacy fixam linhas incompatíveis de Torch e devem ser
instalados em ambientes virtuais separados.
Esse caminho ainda exige forward-1024.pt e backward-1024.pt. Informe cópias
locais verificadas:
export PORTNOIE_FLAIR_FORWARD=/modelos/flair/forward-1024.pt
export PORTNOIE_FLAIR_BACKWARD=/modelos/flair/backward-1024.ptO fallback histórico usa endpoints HTTP e fica desativado por padrão. O opt-in
--allow-historical-download existe apenas para reprodução controlada; não é
necessário nem consultado pelo backend moderno.
O container usa o backend moderno:
docker build -t portnoie .
docker run --rm portnoie doctor
docker run --rm portnoie extract "Maria escreveu um livro."Também é possível executar docker compose run --rm portnoie doctor. O
Dockerfile não instala AllenNLP/Flair nem baixa os assets Flair externos. Durante o
build, baixa o checkpoint verificado para o cache do usuário não-root e instala
pt_core_news_lg==3.8.0 pela URL com hash fixado; a imagem pronta pode executar
sem acesso à rede.
python -m pip install -e ".[modern,dev]"
portnoie download
ruff check src tests scripts
pytest
python -m buildOs testes leves não carregam a rede. Quando Torch está disponível, um teste
offline carrega o checkpoint real e valida a frase anotada; outro percorre o
fluxo de texto bruto com anotações spaCy simuladas. O teste com
pt_core_news_lg real é executado quando esse modelo está instalado. A CI roda
o backend moderno em Python 3.10, 3.11, 3.12 e 3.13.
src/portnoie/ API, CLI, diagnóstico e núcleo moderno
src/portnoie/official.py revisão e hashes oficiais ancorados no pacote
src/portnoie/modern_data/ sidecar mínimo com proveniência
src/portnoie/model_data/ cópia local opcional; excluída do wheel/sdist
multioie/ implementação AllenNLP histórica
tests/ testes unitários e validação offline
scripts/ verificações de procedência e E2E
O relatório e o script reproduzível da comparação Flair 14/14 estão em docs/MODERN_VALIDATION.md. O guia de release descreve a publicação no PyPI/GitHub e os testes exigidos antes de cada tag.
O backend moderno usa Torch ≥2.10 e carrega somente tensores com
weights_only=True. O legado pode abrir o model_params.pkl, que é um pickle
capaz de executar código; use somente a cópia oficial verificada contra os
hashes oficiais do pacote. Consulte
SECURITY.md.
Para trabalhos acadêmicos, cite o artigo associado (a referência também está em CITATION.cff):
@inproceedings{cabral2022portnoie,
author = {Cabral, Bruno and Souza, Marlo and Claro, Daniela Barreiro},
title = {PortNOIE: A Neural Framework for Open Information Extraction for the Portuguese Language},
booktitle = {Computational Processing of the Portuguese Language (PROPOR 2022)},
year = {2022},
doi = {10.1007/978-3-030-98305-5_23}
}A release usa GPL-3.0-only. O arquivo LICENCE original estava vazio e o metadata
antigo dizia apenas GPL-3.; a autorização explícita do mantenedor para publicar o
código, o checkpoint e as matrizes incorporadas foi registrada em 30/08/2026 no
NOTICE.