fa5bcca155
- glirel_load_model: cache por (model_name, device); device='auto' resuelve via torch - extract_relations_glirel: tokeniza por whitespace, mapea spans char->token, llama predict_relations y devuelve RelationCandidate; fallback text.find si la entidad llega sin offsets; max_pairs=N -> top-N por score - pyproject.toml: glirel en extra nlp Closes #0039 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.1 KiB
6.1 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | params | output | tested | tests | test_file_path | file_path | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| extract_relations_glirel | function | py | datascience | 1.0.0 | impure | def extract_relations_glirel(text: str, entities: list[EntityCandidate], relation_types: list[str], model: Any, threshold: float = 0.5, max_pairs: int = 0) -> list[RelationCandidate] | Extrae relaciones zero-shot con GLiREL. Drop-in del contrato de extract_relations_llm pero sin coste por token y mas rapido para corpus grandes. Tokeniza por whitespace, mapea spans de entidades (de attributes['start'/'end'] o fallback text.find) a indices de tokens, y devuelve RelationCandidate cuyos from_name/to_name siempre coinciden con entidades del input. |
|
|
|
|
false | error_go_core |
|
|
lista de RelationCandidate(from_name, to_name, relation_type, description='', confidence). from_name/to_name siempre coinciden con entidades del input. | true |
|
python/functions/datascience/tests/test_extract_relations_glirel.py | python/functions/datascience/extract_relations_glirel.py |
Ejemplo
from python.functions.datascience import (
glirel_load_model,
extract_relations_glirel,
)
from python.types.datascience.entity_candidate import EntityCandidate
model = glirel_load_model(device="auto")
text = "Alice Johnson works at OpenAI in San Francisco."
entities = [
EntityCandidate(name="Alice Johnson", type_label="Person",
attributes={"start": 0, "end": 13}, confidence=0.92),
EntityCandidate(name="OpenAI", type_label="Organization",
attributes={"start": 23, "end": 29}, confidence=0.87),
EntityCandidate(name="San Francisco", type_label="Location",
attributes={"start": 33, "end": 46}, confidence=0.81),
]
relations = extract_relations_glirel(
text=text,
entities=entities,
relation_types=["works_for", "located_in", "owns"],
model=model,
threshold=0.5,
)
# [RelationCandidate(from_name='Alice Johnson', to_name='OpenAI',
# relation_type='works_for', confidence=0.91), ...]
Drop-in con extract_relations_llm
El retorno es identico (list[RelationCandidate]) y from_name/to_name siempre
coinciden con entidades del input — deduplicate_relations_py_datascience lo
acepta sin cambios. Diferencias:
- Coste: GLiREL = 0 USD/token. LLM = depende del modelo.
- Latencia: GLiREL es mucho mas rapido en GPU; en CPU depende del numero de pares (entidades x relation_types).
- Razonamiento implicito: el LLM lo deduce ("CEO de la empresa" -> persona works_for empresa); GLiREL solo extrae lo explicito en el texto.
- Esquemas grandes: GLiREL escala bien con muchos relation_types; el LLM pierde foco con esquemas muy largos.
- Idiomas: GLiREL-large-v0 esta entrenado principalmente en ingles. Para ES evaluar precision/recall caso a caso o caer al LLM.
Spans de entidades
GLiREL necesita los spans (token indices) de cada entidad en el texto. Esta funcion:
- Lee
attributes["start"]yattributes["end"](offsets de caracteres) si existen — el output natural deextract_entities_glineryextract_iocs. - Si faltan, usa
text.find(entity.name)como fallback (con warning). - Tokeniza por whitespace y mapea cada char span a un span de tokens
(
[start_token, end_token]). - Pasa todo a
model.predict_relations(tokens, labels=..., ner=...).
Si la entidad no se puede localizar en el texto, se descarta (no se le pueden buscar relaciones sin saber donde esta).
Notas
- impure: el modelo es estado externo.
error_type: error_go_coresegun la regla de pureza del registry. - Si dos entidades tienen el mismo nombre, GLiREL podria mezclarlas; el matcheo
por
head_pos/tail_pos(token start) las distingue mejor quehead_text. - Una
relation_typeque no aparece en el output NO es un error — solo significa que GLiREL no encontro evidencia. - Combinar con LLM para razonamiento implicito: ver issue 0040 (pipeline hibrido).
- Para precision maxima, ajustar
thresholdpor dominio: 0.3-0.4 = recall alto; 0.6-0.8 = precision alta.
Limitacion
GLiREL es bueno para relaciones explicitas en el texto (X trabaja en Y,
A llamo a B), malo para razonamiento implicito (la nueva CEO, su empresa).
Para razonamiento implicito seguir usando extract_relations_llm. El pipeline
hibrido (issue 0040) compone GLiREL para extraccion masiva + LLM para los casos
implicitos que GLiREL no cubre.