Troubleshooting Guide
March 7, 2025 ยท View on GitHub
This guide addresses common issues you might encounter when using Hapax and provides solutions.
Table of Contents
- Installation Issues
- Type Errors
- Graph Validation Errors
- Execution Errors
- OpenLIT Integration Issues
- GPU Monitoring Issues
- Evaluation Issues
- Performance Considerations
Installation Issues
Cannot install hapax due to dependency conflicts
Problem:
ERROR: Cannot install hapax due to incompatible dependencies: openlit requires opentelemetry>=1.20.0
Solution:
- Create a fresh virtual environment:
python -m venv fresh_env source fresh_env/bin/activate # On Windows: fresh_env\Scripts\activate - Install with explicit version specification:
pip install "hapax[all]" --upgrade
Missing Optional Dependencies
Problem:
ImportError: Cannot import name 'HallucinationEvaluator' from 'hapax'
Solution: Install the appropriate optional dependencies:
pip install "hapax[eval]" # For evaluators
pip install "hapax[gpu]" # For GPU monitoring
pip install "hapax[all]" # For all features
Type Errors
Incompatible Types in Operation Composition
Problem:
TypeError: Cannot compose operations: output type List[str] does not match input type Dict[str, Any]
Solution:
-
Check your operation type hints:
@ops def tokenize(text: str) -> List[str]: # Returns List[str] return text.split() @ops def count_words(tokens: List[str]) -> Dict[str, int]: # Expects List[str] from collections import Counter return dict(Counter(tokens)) # Correct composition pipeline = tokenize >> count_words -
Add a transformation operation between incompatible operations:
@ops def transform(items: List[str]) -> Dict[str, Any]: return {"items": items} pipeline = tokenize >> transform >> dict_processor
Runtime Type Errors
Problem:
TypeError: Expected str but got int for argument 'text'
Solution:
-
Ensure proper input types when calling operations:
result = text_operation("Hello") # Correct # result = text_operation(123) # Wrong -
Add explicit type conversion where needed:
@ops def ensure_string(value: Any) -> str: return str(value) pipeline = ensure_string >> text_operation
Graph Validation Errors
Cycle Detected in Graph
Problem:
GraphValidationError: Graph contains cycles: [['op1', 'op2', 'op1']]
Solution:
- Verify your graph structure doesn't have circular references
- Use
Loopexplicitly for intended repetition:from hapax.core.flow import Loop loop = Loop( "process_loop", process_operation, condition=lambda x: x.is_complete, max_iterations=10 )
Missing Operation in Graph
Problem:
GraphValidationError: Operation 'cleanup' referenced but not defined
Solution:
- Ensure all operations are properly defined before using them in a graph
- Check for typos in operation names
- Verify the operation is imported in the current scope
Execution Errors
Branch Errors
Problem:
BranchError: Errors in branches: [('sentiment', ValueError('Invalid input'))]
Solution:
-
Handle branch errors explicitly:
try: result = pipeline.execute(input_data) except BranchError as e: print(f"Branch errors: {e.branch_errors}") print(f"Partial results: {e.partial_results}") # Use partial results or fallback strategy -
Add validation and error handling in branch operations:
@ops def safe_sentiment(text: str) -> float: try: # Potentially risky operation return calculate_sentiment(text) except Exception: # Fallback return 0.0
Memory Errors with Large Graphs
Problem:
MemoryError: Unable to allocate memory for graph execution
Solution:
- Process data in smaller batches
- Implement streaming operations
- Add garbage collection in long-running operations:
@ops def memory_intensive(data: List[Any]) -> Any: import gc result = process_large_data(data) gc.collect() # Explicitly run garbage collection return result
OpenLIT Integration Issues
Connection Refused
Problem:
ConnectionRefusedError: [Errno 111] Connection refused - OpenLIT endpoint not available
Solution:
- Verify your OpenLIT endpoint is running:
# Check if the port is open nc -zv localhost 4318 - Update your endpoint configuration:
openlit.init(otlp_endpoint="http://localhost:4318") - If you don't have an OpenLIT backend, disable monitoring:
set_openlit_config(None) # Disable OpenLIT integration
Missing Metrics or Traces
Problem: Operations execute but metrics/traces are not appearing in your monitoring system.
Solution:
-
Verify OpenLIT initialization occurs before operation execution:
import openlit # Initialize OpenLIT first openlit.init(otlp_endpoint="http://localhost:4318") # Then define and use operations @ops def my_operation(x: int) -> int: return x + 1 -
Check OpenLIT configuration:
from hapax import set_openlit_config set_openlit_config({ "trace_content": True, # Enable content tracing "disable_metrics": False, # Ensure metrics are enabled "otlp_endpoint": "http://localhost:4318" })
GPU Monitoring Issues
GPU Metrics Not Available
Problem: get_gpu_metrics() returns empty results or errors.
Solution:
- Verify NVIDIA drivers are installed and accessible
- Check optional dependencies:
pip install "hapax[gpu]" - Ensure GPU monitoring is enabled:
from hapax import enable_gpu_monitoring enable_gpu_monitoring(sample_rate_seconds=1)
Evaluation Issues
API Key Not Found
Problem:
KeyError: Provider API key not found for OpenAI/Anthropic
Solution:
- Set API keys as environment variables:
export OPENAI_API_KEY=your_key_here export ANTHROPIC_API_KEY=your_key_here - Or pass explicitly:
evaluator = HallucinationEvaluator( provider="openai", api_key="your_key_here" )
Evaluation Always Fails/Passes
Problem: Evaluations always return the same result regardless of content.
Solution:
- Adjust threshold values:
@eval(evals=["toxicity"], threshold=0.7) # Higher threshold = more permissive - Check your evaluator implementation or provider settings
- Add debug logging:
@eval( evals=["toxicity"], openlit_config={"trace_content": True, "log_level": "DEBUG"} )
Performance Considerations
Slow Graph Execution
Problem: Graph execution is slower than expected.
Solution:
-
Profile your operations to identify bottlenecks:
import time @ops def timed_operation(data: Any) -> Any: start = time.time() result = process(data) duration = time.time() - start print(f"Operation took {duration:.2f} seconds") return result -
Parallelize independent operations with Branch:
pipeline = ( Graph("parallel_processing") .branch( heavy_operation_1, heavy_operation_2 ) .merge(combine_results) ) -
Use caching for expensive operations:
from functools import lru_cache @lru_cache(maxsize=100) def expensive_computation(data: str) -> Any: # Expensive processing return result @ops def cached_operation(data: str) -> Any: return expensive_computation(data)
High Memory Usage
Problem: Memory usage grows excessively during graph execution.
Solution:
-
Process data in smaller chunks
-
Implement generators for large datasets:
@ops def process_batches(data_source: Any) -> List[Any]: results = [] for batch in get_batches(data_source, batch_size=100): result = process_batch(batch) results.append(result) return results -
Add explicit cleanup in operations:
@ops def cleanup_after(data: Any) -> Any: result = process(data) # Explicit cleanup import gc gc.collect() return result
Still Having Issues?
If you're still experiencing problems:
- Check the GitHub Issues for similar problems
- Join our [Community Slack/Discord] for real-time help
- File a detailed bug report with:
- Hapax version
- Python version
- Operating system
- Complete error traceback
- Minimal code example to reproduce the issue