mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-08-29 04:26:20 +00:00
Harden spaCy NER fallback in semantic extract
This commit is contained in:
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- **spaCy Runtime Fallback for NER Benchmarks**:
|
||||
- Hardened `NERExtractor` spaCy initialization so installed-but-broken spaCy environments no longer crash during extractor construction.
|
||||
- Updated ML entity extraction fallback behavior to catch runtime spaCy initialization failures, not just missing-model errors.
|
||||
- Added regression coverage for the "spaCy present but unusable at runtime" initialization path.
|
||||
|
||||
### Added
|
||||
- **Configurable LLM Retry Logic**:
|
||||
- Exposed `max_retries` parameter in `NERExtractor`, `RelationExtractor`, `TripletExtractor` and low-level extraction methods (`extract_entities_llm`, `extract_relations_llm`, `extract_triplets_llm`).
|
||||
|
||||
@@ -683,6 +683,16 @@ def extract_entities_ml(
|
||||
"spaCy model not available, falling back to pattern extraction"
|
||||
)
|
||||
return extract_entities_pattern(text, **kwargs)
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
f"spaCy model failed to initialize ({exc}), falling back to pattern extraction"
|
||||
)
|
||||
return extract_entities_pattern(text, **kwargs)
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
f"spaCy model {model} failed to initialize ({exc}), falling back to pattern extraction"
|
||||
)
|
||||
return extract_entities_pattern(text, **kwargs)
|
||||
|
||||
doc = nlp(text)
|
||||
entities = []
|
||||
|
||||
@@ -154,6 +154,10 @@ class NERExtractor:
|
||||
self.logger.warning(
|
||||
f"spaCy model {self.model_name} not found. ML method will fallback."
|
||||
)
|
||||
except Exception as exc:
|
||||
self.logger.warning(
|
||||
f"spaCy model {self.model_name} failed to initialize ({exc}). ML method will fallback."
|
||||
)
|
||||
|
||||
def extract(self, text: Union[str, List[Dict[str, Any]], List[str]], pipeline_id: Optional[str] = None, **kwargs) -> Union[List[Entity], List[List[Entity]]]:
|
||||
"""
|
||||
|
||||
@@ -101,6 +101,16 @@ class TestNERConfigurations(unittest.TestCase):
|
||||
self.assertEqual(entities[0].metadata["extraction_method"], "ml")
|
||||
self.assertEqual(entities[0].metadata["model"], "en_core_web_trf")
|
||||
|
||||
@patch('semantica.semantic_extract.ner_extractor.spacy')
|
||||
def test_ner_ml_init_falls_back_when_spacy_runtime_is_broken(self, mock_spacy):
|
||||
"""Test NER init does not crash when spaCy is installed but unusable at runtime."""
|
||||
mock_spacy.load.side_effect = RuntimeError("ConfigSchemaNlp is not fully defined")
|
||||
|
||||
with patch('semantica.semantic_extract.ner_extractor.SPACY_AVAILABLE', True):
|
||||
extractor = NERExtractor(method="ml", model="en_core_web_sm")
|
||||
|
||||
self.assertIsNone(extractor.nlp)
|
||||
|
||||
def test_ner_regex_config(self):
|
||||
"""Test NER with Regex configuration"""
|
||||
print("\nTesting NER with Regex configuration...")
|
||||
|
||||
Reference in New Issue
Block a user