KeyNeg-RS
Rust-powered sentiment analysis with Python bindings. 10-100x faster than pure Python.
Why KeyNeg-RS?
10-100x Faster
Native Rust performance with ONNX Runtime inference. Process thousands of documents in seconds.
Low Latency
Single text analysis in ~3ms vs ~45ms in Python. Perfect for real-time applications.
Cross-Platform
Pre-built wheels for Windows, macOS (Intel & Apple Silicon). Python 3.9-3.12.
Enterprise Ready
30-day trial, domain-bound licensing. Same API as KeyNeg Enterprise.
Installation
KeyNeg-RS is distributed via our private PyPI server.
From Private PyPI Server
pip install keyneg-enterprise-rs \
--index-url https://pypi.grandnasser.com/simple/ \
--trusted-host pypi.grandnasser.com
When prompted, enter the credentials provided in your welcome email.
Supported Platforms
| Platform | Architecture | Python Versions |
|---|---|---|
| Windows | x64 | 3.9, 3.10, 3.11, 3.12 |
| macOS | Intel (x86_64) | 3.9, 3.10, 3.11, 3.12 |
| macOS | Apple Silicon (ARM64) | 3.9, 3.10, 3.11, 3.12 |
Model Setup
KeyNeg-RS uses ONNX models for inference. You can either export the model yourself or download from HuggingFace.
Install Export Dependencies
pip install keyneg-enterprise-rs[model-export]
Export the Model
# Using the CLI tool
keyneg-export-model --output-dir ./models
This creates:
models/model.onnx- ONNX model (~418 MB)models/tokenizer.json- Tokenizer file
Quick Start
from keyneg import KeyNeg, version
# Check version
print(f"KeyNeg-RS version: {version()}")
# Initialize with model paths
kn = KeyNeg("models/model.onnx", "models/tokenizer.json")
# Analyze text
text = "The work environment is toxic and management is incompetent."
# Extract sentiments
sentiments = kn.extract_sentiments(text, top_n=5)
for label, score in sentiments:
print(f"{label}: {score:.3f}")
# Output:
# hostile work environment: 0.603
# toxic culture: 0.453
# incompetent management: 0.533
Extract Sentiments
sentiments = kn.extract_sentiments(
doc="The toxic culture and micromanagement is unbearable",
top_n=5,
threshold=0.3,
diversity=0.0
)
for label, score in sentiments:
print(f"{label}: {score:.3f}")
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
doc | str | required | Input text to analyze |
top_n | int | 5 | Number of sentiments to return |
threshold | float | 0.3 | Minimum similarity score |
diversity | float | 0.0 | MMR diversity factor (0-1) |
Extract Keywords
keywords = kn.extract_keywords(
doc="Poor communication and lack of transparency from leadership",
top_n=10,
threshold=0.25,
keyphrase_ngram_range=(1, 2),
use_taxonomy=True,
diversity=0.0
)
for keyword, score in keywords:
print(f"{keyword}: {score:.3f}")
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
doc | str | required | Input text to analyze |
top_n | int | 10 | Number of keywords to return |
threshold | float | 0.25 | Minimum similarity score |
keyphrase_ngram_range | tuple | (1, 2) | N-gram range for keyphrases |
use_taxonomy | bool | True | Use built-in taxonomy matching |
diversity | float | 0.0 | MMR diversity factor (0-1) |
Full Analysis
result = kn.analyze(
doc="The management style is terrible and there's no work-life balance.",
top_n_keywords=10,
top_n_sentiments=5
)
print(f"Text length: {result['text_length']}")
print(f"Word count: {result['word_count']}")
print(f"Keywords: {result['keywords']}")
print(f"Sentiments: {result['sentiments']}")
Returns
{
'keywords': [('terrible', 0.71), ('management style', 0.65), ...],
'sentiments': [('poor work-life balance', 0.62), ...],
'text_length': 72,
'word_count': 12
}
Batch Processing
Process multiple documents efficiently with parallelized batch analysis:
documents = [
"I hate my job",
"The management is terrible",
"No work-life balance at all",
"Toxic environment with constant pressure",
]
results = kn.analyze_batch(documents, top_n_keywords=5, top_n_sentiments=3)
for i, result in enumerate(results):
print(f"Doc {i+1}: {result['sentiments'][0][0]} ({result['sentiments'][0][1]:.2f})")
Batch processing is significantly faster than processing documents one by one. For 1000 documents, batch processing can be 25-37x faster than the Python version.
Benchmarks
Performance comparison on Intel i7-12700K, 32GB RAM:
| Operation | Python (KeyNeg) | Rust (KeyNeg-RS) | Speedup |
|---|---|---|---|
| Single text analysis | 45ms | 3.2ms | 14x |
| Batch (100 docs) | 4.5s | 180ms | 25x |
| Batch (1000 docs) | 45s | 1.2s | 37x |
- Native Rust code with zero-copy memory operations
- ONNX Runtime with optimized CPU/GPU inference
- Parallel batch processing via Rayon
- Efficient embedding caching
Optimization Tips
Use Batch Processing
# Good: Process all at once
results = kn.analyze_batch(all_documents)
# Bad: Process one by one
results = [kn.analyze(doc) for doc in all_documents]
Reuse the KeyNeg Instance
# Good: Create once, use many times
kn = KeyNeg("models/model.onnx", "models/tokenizer.json")
for doc in documents:
result = kn.analyze(doc)
# Bad: Create new instance for each document
for doc in documents:
kn = KeyNeg("models/model.onnx", "models/tokenizer.json")
result = kn.analyze(doc)
ONNX Runtime Path (Windows)
If you have system ONNX Runtime conflicts, set the correct path:
# Windows PowerShell
$env:ORT_DYLIB_PATH = "path\to\onnxruntime.dll"
# Or in Python
import os
os.environ["ORT_DYLIB_PATH"] = "path/to/onnxruntime.dll"
Licensing
KeyNeg-RS includes a 30-day free trial. Check your license status:
from keyneg import check_trial_status, activate_license_key
# Check trial status
status = check_trial_status()
print(f"License: {status['license_type']}")
print(f"Days remaining: {status['days_remaining']}")
# Activate full license
activate_license_key("KN-ENT-xxxxxxxxxxxx-xxxxxxxx", domain="yourcompany.com")
API Reference
KeyNeg Class
| Method | Description |
|---|---|
__init__(model_path, tokenizer_path) | Initialize with ONNX model and tokenizer paths |
extract_sentiments(doc, ...) | Extract sentiment labels from text |
extract_keywords(doc, ...) | Extract keywords from text |
extract_keywords_detailed(doc, ...) | Extract keywords with category info |
analyze(doc, ...) | Full analysis (keywords + sentiments) |
analyze_batch(docs, ...) | Batch analysis for multiple documents |
get_license_info() | Get current license information |
Module Functions
| Function | Description |
|---|---|
version() | Get library version string |
check_trial_status() | Check trial license status |
activate_license_key(key, domain) | Activate enterprise license |
get_sentiment_labels() | Get list of all sentiment labels |
get_default_taxonomy() | Get default negative taxonomy dict |
Troubleshooting
"ONNX Runtime version mismatch" Error
Your system has a different ONNX Runtime version. Install the compatible version:
pip install onnxruntime==1.22.0
Or set the ORT_DYLIB_PATH environment variable to point to the correct DLL.
"Invalid input name: token_type_ids" Error
Upgrade to KeyNeg-RS v1.0.1 or later which handles models without token_type_ids.
"Cannot import KeyNeg" Error
If you have the Python keyneg package installed, uninstall it first:
pip uninstall keyneg
pip install keyneg-enterprise-rs --force-reinstall
Model file not found
Make sure to export the ONNX model first:
keyneg-export-model --output-dir ./models
Support
Enterprise customers receive priority support:
- Email: admin@grandnasser.com
- Response Time: Within 24 business hours
- GitHub: Issue Tracker
Ready to Get Started?
Contact us for pricing and to start your 30-day free trial.
Contact for Pricing