Elevator pitch: Automatically identify software mentions in scientific papers at scale to improve reproducibility and enable software impact analysis.
Reproducibility in science depends on knowing which software a paper used. Unfortunately, PDF text seldom marks software explicitly, and manual identification is impossible at scale. This project recovers software mentions from millions of academic papers using advanced NLP techniques.
{bibcode, title, abstract, body} fieldsFor newcomers who want instant success without downloading 3GB corpus:
# 1. Setup environment
git clone https://github.com/adsabs/entity_extractor
cd entity_extractor
python -m venv venv && source venv/bin/activate
# 2. Install dependencies
pip install -r software_mentions_pipeline/requirements.txt
# 3. Run with sample data
python software_mentions_pipeline/load_inputs.py --sample
python streamlit_dashboard/launch_app.py
Open http://localhost:8501 for an interactive interface with sample data included.
optimized_extractor/ - Experimental fast Cython/regex prototype (WIP)
streamlit_dashboard/ - Web UI for quick experimentation and parameter tuning
AGENT.md - Development environment configuration and commands
Note: If running this on scixmuse the virtual environment has already been created and so you just need to cd to entity_extractor, type source venv/bin/activate, then cd to streamlit_dashboard and type streamlit run app.py
# 1. Environment setup
python -m venv venv && source venv/bin/activate
pip install --upgrade pip setuptools wheel
# 2. Install dependencies
pip install -r software_mentions_pipeline/requirements.txt
# 3. Install development tools (optional but recommended)
pip install black isort flake8 mypy pytest pre-commit
# 4. Setup pre-commit hooks (optional)
pre-commit install
# 5. Test installation
python software_mentions_pipeline/test_indus_ner_tags.py
source venv/bin/activate - Activate virtual environment (ALWAYS FIRST)pip install -r software_mentions_pipeline/requirements.txt - Install dependenciespip list | grep -E "(transformers|sentence-transformers|streamlit)" - Verify key packagespython software_mentions_pipeline/test_indus_ner_tags.py - Test NER model functionalitypytest software_mentions_pipeline/tests/ - Run unit tests (if available)python -c "import transformers; print('✓ Transformers OK')" - Quick dependency checkpython software_mentions_pipeline/load_inputs.py - Initialize database and load corpus/metadatapython software_mentions_pipeline/batch_filter.py - Stage 1: Extract exact/fuzzy matches
batch_filter_context.py - Context-level filtering approachpython software_mentions_pipeline/embed_contextual_mentions.py - Generate embeddings for contexts
embed_software_library.py - Pre-compute registry embeddingspython software_mentions_pipeline/score_filtered_contexts.py - Score context similarity
score_likelihoods_and_filter.py - Experimental scoringpython software_mentions_pipeline/assign_likelihood_labels.py - Assign likelihood scorespython software_mentions_pipeline/labeling_tool.py - Manual labeling interfacepython software_mentions_pipeline/export_ner_training_data.py - Export training datastreamlit run streamlit_dashboard/app.py - Launch streamlit dashboardEntity extraction pipeline for scientific literature using NLP and ML:
candidates table storing matches, contexts, embeddings, classificationsgraph LR
A[corpus.jsonl<br/>3GB papers] -->|Stage 1| B(load_inputs.py)
B -->|labels.json| C{Filtering Approach}
C -->|Standard| D[batch_filter.py]
C -->|Context-based| E[batch_filter_context.py]
D -->|context windows| F(embed_contextual_mentions.py)
E -->|context windows| F
F -->|vectors| G{Scoring Approach}
G -->|Standard| H[score_filtered_contexts.py]
G -->|Experimental| I[score_likelihoods_and_filter.py]
H -->|scores+signals| J[assign_likelihood_labels.py]
I -->|scores+signals| J
J -->|labeled data| K[labeling_tool.py]
K -->|validated labels| L[export_ner_training_data.py]
M[OntoSoft Registry] --> B
N[ASCL Registry] --> B
O[Custom Ontologies] --> B
P[embed_software_library.py] -.->|pre-computed embeddings| F
Data Loading (load_inputs.py)
Exact Matching (batch_filter.py)
Context Embedding (embed_contextual_mentions.py)
Multi-Signal Scoring (score_filtered_contexts.py)
Classification (assign_likelihood_labels.py)
Export & Validation
The pipeline uses a novel span-aware approach for NER validation that prevents term fragmentation:
Problem: Traditional NER aggregation strategies can split matched terms due to tokenization. For example, "Zeus" might be tokenized as "ze" + "##us" and only partially recognized.
Solution: We use aggregation_strategy="none" and implement span-aware classification:
# Load NER models with raw token output
ner_pipe = pipeline(
"token-classification",
model="oeg/software_benchmark_multidomain",
aggregation_strategy="none" # Preserve character offsets
)
# Classify only tokens within the known matched span
def run_ner_on_span(text, matched_term, model_key):
# Find exact character positions of the matched term
span_start = text.lower().find(matched_term.lower())
span_end = span_start + len(matched_term)
# Run NER and check only overlapping tokens
for token in ner_pipe(text):
if token_overlaps_span(token, span_start, span_end):
if token_is_software_labeled(token):
return True
return False
This approach guarantees that:
Document key environment variables in code:
SOFTEXTRACT_DB_PATH - Override default database locationHF_HOME - HuggingFace cache directoryCUDA_VISIBLE_DEVICES - GPU selection for embedding generationSTREAMLIT_SERVER_PORT - Dashboard port configurationexcept:nasa-impact/nasa-smd-ibm-st-v2oeg/software_benchmark_multidomainadsabs/nasa-smd-ibm-v0.1_NER_DEAL (INDUS)The system works with a large-scale curated dataset:
optimized_extractor/results/exports/software_mentions_all_with_labels.csv.gzipThe interactive dashboard provides comprehensive tools for reviewing and curating software mentions:
Autocomplete Search:
Context Categorization:
Multi-Model NER Analysis:
adsabs/nasa-smd-ibm-v0.1_NER_DEAL): Domain-specific astrophysics modeloeg/software_benchmark_multidomain): Specialized software entity extraction modelLabel Curation System:
curation_delta.csv) preserves main datasetStatistics & Navigation:
# Activate environment and launch
source venv/bin/activate
streamlit run streamlit_dashboard/app.py
# Open http://localhost:8501
Create registry file: Drop my_registry.json with required fields:
{
"software_name": {
"name": "MyTool",
"description": "Description for embedding similarity",
"url": "https://example.com"
}
}
Load into pipeline: python load_inputs.py --ontology data/my_registry.json
Optional pre-embedding: python embed_software_library.py --file data/my_registry.json
Create signal module: Write signals/my_signal.py with function:
def score(context_row: dict) -> float:
"""Return 0.0-1.0 confidence score for this context"""
return confidence_score
Register in scorer: Import and add to score_filtered_contexts.py
Configure weight: Update signal weight in configuration
streamlit_dashboard/components/CUDA OOM during embedding
# Reduce batch size or use CPU
python embed_contextual_mentions.py --batch-size 16
python embed_contextual_mentions.py --device cpu
SQLite database locked error
# Ensure single writer process, check for zombie connections
sqlite3 data/candidates.db "PRAGMA journal_mode=WAL;"
FileNotFoundError: corpus.jsonl
# Verify data path or specify custom location
python load_inputs.py --corpus /path/to/my_corpus.jsonl
HuggingFace model download timeout
export HF_HUB_DISABLE_PROGRESS_BARS=1
pip install --upgrade transformers
Streamlit port conflict
python launch_app.py --port 8502
nvidia-smi during embedding generationSee AGENT.md for detailed development setup, commands, and coding standards.
GitHub: https://github.com/adsabs/entity_extractor
Part of the ADS (Astrophysics Data System) project by the Smithsonian Astrophysical Observatory.
Elevator pitch: Automatically identify software mentions in scientific papers at scale to improve reproducibility and enable software impact analysis.
Reproducibility in science depends on knowing which software a paper used. Unfortunately, PDF text seldom marks software explicitly, and manual identification is impossible at scale. This project recovers software mentions from millions of academic papers using advanced NLP techniques.
{bibcode, title, abstract, body} fieldsFor newcomers who want instant success without downloading 3GB corpus:
# 1. Setup environment
git clone https://github.com/adsabs/entity_extractor
cd entity_extractor
python -m venv venv && source venv/bin/activate
# 2. Install dependencies
pip install -r software_mentions_pipeline/requirements.txt
# 3. Run with sample data
python software_mentions_pipeline/load_inputs.py --sample
python streamlit_dashboard/launch_app.py
Open http://localhost:8501 for an interactive interface with sample data included.
optimized_extractor/ - Experimental fast Cython/regex prototype (WIP)
streamlit_dashboard/ - Web UI for quick experimentation and parameter tuning
AGENT.md - Development environment configuration and commands
Note: If running this on scixmuse the virtual environment has already been created and so you just need to cd to entity_extractor, type source venv/bin/activate, then cd to streamlit_dashboard and type streamlit run app.py
# 1. Environment setup
python -m venv venv && source venv/bin/activate
pip install --upgrade pip setuptools wheel
# 2. Install dependencies
pip install -r software_mentions_pipeline/requirements.txt
# 3. Install development tools (optional but recommended)
pip install black isort flake8 mypy pytest pre-commit
# 4. Setup pre-commit hooks (optional)
pre-commit install
# 5. Test installation
python software_mentions_pipeline/test_indus_ner_tags.py
source venv/bin/activate - Activate virtual environment (ALWAYS FIRST)pip install -r software_mentions_pipeline/requirements.txt - Install dependenciespip list | grep -E "(transformers|sentence-transformers|streamlit)" - Verify key packagespython software_mentions_pipeline/test_indus_ner_tags.py - Test NER model functionalitypytest software_mentions_pipeline/tests/ - Run unit tests (if available)python -c "import transformers; print('✓ Transformers OK')" - Quick dependency checkpython software_mentions_pipeline/load_inputs.py - Initialize database and load corpus/metadatapython software_mentions_pipeline/batch_filter.py - Stage 1: Extract exact/fuzzy matches
batch_filter_context.py - Context-level filtering approachpython software_mentions_pipeline/embed_contextual_mentions.py - Generate embeddings for contexts
embed_software_library.py - Pre-compute registry embeddingspython software_mentions_pipeline/score_filtered_contexts.py - Score context similarity
score_likelihoods_and_filter.py - Experimental scoringpython software_mentions_pipeline/assign_likelihood_labels.py - Assign likelihood scorespython software_mentions_pipeline/labeling_tool.py - Manual labeling interfacepython software_mentions_pipeline/export_ner_training_data.py - Export training datastreamlit run streamlit_dashboard/app.py - Launch streamlit dashboardEntity extraction pipeline for scientific literature using NLP and ML:
candidates table storing matches, contexts, embeddings, classificationsgraph LR
A[corpus.jsonl<br/>3GB papers] -->|Stage 1| B(load_inputs.py)
B -->|labels.json| C{Filtering Approach}
C -->|Standard| D[batch_filter.py]
C -->|Context-based| E[batch_filter_context.py]
D -->|context windows| F(embed_contextual_mentions.py)
E -->|context windows| F
F -->|vectors| G{Scoring Approach}
G -->|Standard| H[score_filtered_contexts.py]
G -->|Experimental| I[score_likelihoods_and_filter.py]
H -->|scores+signals| J[assign_likelihood_labels.py]
I -->|scores+signals| J
J -->|labeled data| K[labeling_tool.py]
K -->|validated labels| L[export_ner_training_data.py]
M[OntoSoft Registry] --> B
N[ASCL Registry] --> B
O[Custom Ontologies] --> B
P[embed_software_library.py] -.->|pre-computed embeddings| F
Data Loading (load_inputs.py)
Exact Matching (batch_filter.py)
Context Embedding (embed_contextual_mentions.py)
Multi-Signal Scoring (score_filtered_contexts.py)
Classification (assign_likelihood_labels.py)
Export & Validation
The pipeline uses a novel span-aware approach for NER validation that prevents term fragmentation:
Problem: Traditional NER aggregation strategies can split matched terms due to tokenization. For example, "Zeus" might be tokenized as "ze" + "##us" and only partially recognized.
Solution: We use aggregation_strategy="none" and implement span-aware classification:
# Load NER models with raw token output
ner_pipe = pipeline(
"token-classification",
model="oeg/software_benchmark_multidomain",
aggregation_strategy="none" # Preserve character offsets
)
# Classify only tokens within the known matched span
def run_ner_on_span(text, matched_term, model_key):
# Find exact character positions of the matched term
span_start = text.lower().find(matched_term.lower())
span_end = span_start + len(matched_term)
# Run NER and check only overlapping tokens
for token in ner_pipe(text):
if token_overlaps_span(token, span_start, span_end):
if token_is_software_labeled(token):
return True
return False
This approach guarantees that:
Document key environment variables in code:
SOFTEXTRACT_DB_PATH - Override default database locationHF_HOME - HuggingFace cache directoryCUDA_VISIBLE_DEVICES - GPU selection for embedding generationSTREAMLIT_SERVER_PORT - Dashboard port configurationexcept:nasa-impact/nasa-smd-ibm-st-v2oeg/software_benchmark_multidomainadsabs/nasa-smd-ibm-v0.1_NER_DEAL (INDUS)The system works with a large-scale curated dataset:
optimized_extractor/results/exports/software_mentions_all_with_labels.csv.gzipThe interactive dashboard provides comprehensive tools for reviewing and curating software mentions:
Autocomplete Search:
Context Categorization:
Multi-Model NER Analysis:
adsabs/nasa-smd-ibm-v0.1_NER_DEAL): Domain-specific astrophysics modeloeg/software_benchmark_multidomain): Specialized software entity extraction modelLabel Curation System:
curation_delta.csv) preserves main datasetStatistics & Navigation:
# Activate environment and launch
source venv/bin/activate
streamlit run streamlit_dashboard/app.py
# Open http://localhost:8501
Create registry file: Drop my_registry.json with required fields:
{
"software_name": {
"name": "MyTool",
"description": "Description for embedding similarity",
"url": "https://example.com"
}
}
Load into pipeline: python load_inputs.py --ontology data/my_registry.json
Optional pre-embedding: python embed_software_library.py --file data/my_registry.json
Create signal module: Write signals/my_signal.py with function:
def score(context_row: dict) -> float:
"""Return 0.0-1.0 confidence score for this context"""
return confidence_score
Register in scorer: Import and add to score_filtered_contexts.py
Configure weight: Update signal weight in configuration
streamlit_dashboard/components/CUDA OOM during embedding
# Reduce batch size or use CPU
python embed_contextual_mentions.py --batch-size 16
python embed_contextual_mentions.py --device cpu
SQLite database locked error
# Ensure single writer process, check for zombie connections
sqlite3 data/candidates.db "PRAGMA journal_mode=WAL;"
FileNotFoundError: corpus.jsonl
# Verify data path or specify custom location
python load_inputs.py --corpus /path/to/my_corpus.jsonl
HuggingFace model download timeout
export HF_HUB_DISABLE_PROGRESS_BARS=1
pip install --upgrade transformers
Streamlit port conflict
python launch_app.py --port 8502
nvidia-smi during embedding generationSee AGENT.md for detailed development setup, commands, and coding standards.
GitHub: https://github.com/adsabs/entity_extractor
Part of the ADS (Astrophysics Data System) project by the Smithsonian Astrophysical Observatory.