OpenMed Profiling Tools for Performance Debugging: A Complete Guide
OpenMed ships with a built-in openmed.utils.profiling module that provides four complementary utilities—the Profiler class, global helper functions, a @profile decorator, and lightweight Timer tools—to capture detailed execution timings for debugging bottlenecks in medical NLP pipelines.
The maziyarpanahi/openmed repository includes a native performance debugging suite designed specifically for healthcare AI workflows. These OpenMed profiling tools enable developers to measure model loading latency, track inference durations, and identify preprocessing slowdowns without requiring external dependencies. All functionality resides in a single, lightweight module that integrates seamlessly into existing Python codebases.
The openmed.utils.profiling Module Architecture
The profiling suite is implemented in openmed/utils/profiling.py, which defines the core Profiler class, timing data structures, and global state management. According to the OpenMed source code, the module uses a singleton pattern for global profiling sessions while supporting isolated local profiler instances for targeted debugging of specific pipeline components.
Core OpenMed Profiling Components
The Profiler Class for Scoped Measurements
The Profiler class acts as a context-manager-based recorder that accumulates TimingResult objects. In openmed/utils/profiling.py (lines 22-33), the class definition includes an enabled flag and metadata storage capabilities. The measure() method (lines 60-78) creates scoped timers, while report() (lines 15-30) returns a ProfileReport containing all captured timings and statistical breakdowns.
Global Helper Functions
OpenMed provides singleton-based global helpers to enable application-wide profiling without passing instances between functions. The enable_profiling() function (lines 45-52) initializes and starts a global profiler, disable_profiling() (lines 53-58) stops the current session, and get_profile_report() (lines 60-63) retrieves the accumulated timing data. These utilities allow seamless integration into existing pipeline code without refactoring function signatures.
The @profile Decorator
For automatic function-level timing, the @profile decorator (implemented in lines 65-88 of profiling.py) wraps any callable to record its execution duration using the global profiler instance. This approach eliminates the need for explicit with blocks when timing specific functions repeatedly across your medical NLP workflow.
Lightweight Timer and timed Utilities
The Timer class and timed context manager provide ad-hoc measurement capabilities primarily intended for logging and rapid debugging. Timer.start() and Timer.stop() return elapsed milliseconds, while the timed() context manager (lines 55-74) yields a Timer instance and automatically logs results on exit, making it ideal for quick diagnostic statements during development.
Practical Examples for OpenMed Performance Debugging
Manual Profiling with Local Profiler Instances
Use the Profiler class directly when you need isolated timing sessions for specific pipeline sections:
from openmed.utils.profiling import Profiler
profiler = Profiler(enabled=True)
with profiler.measure("load_model"):
model = load_my_model() # <- your costly operation
with profiler.measure("inference"):
result = model.predict(text)
print(profiler.report().format_report())
Global Profiling Sessions
Enable application-wide debugging to capture timings across multiple modules:
from openmed.utils.profiling import enable_profiling, get_profile_report
enable_profiling() # starts a global session
# … run any code that calls `profile()` or `Profiler.measure()` …
report = get_profile_report()
print(report.format_report(include_metadata=True))
Automatic Function Timing with Decorators
Apply the @profile decorator to capture timings without modifying function internals:
from openmed.utils.profiling import profile
@profile("tokenize")
def tokenize(text):
return tokenizer.encode(text)
# each call is timed automatically
tokens = tokenize("Hello world")
Quick Timing with timed Context Managers
Use timed() for lightweight, logging-friendly measurements:
from openmed.utils.profiling import timed
with timed("model inference"):
output = model.predict(batch)
# Logs something like: "model inference took 123.45ms"
Report Generation and Output Formats
All OpenMed profiling tools produce human-readable reports via ProfileReport.format_report() or BatchMetrics.format_report(). These methods output total duration, per-operation breakdowns, and optional metadata, enabling quick identification of bottlenecks in medical model inference workflows.
Testing and Validation
The intended usage patterns and API behaviors are verified in tests/unit/test_profiling.py, which contains comprehensive unit tests for the Profiler class, global helper functions, @profile decorator, and Timer utilities. Developers should reference these tests to understand proper initialization sequences and edge cases for the global profiler singleton.
Summary
- Scoped Profiling: Use the
Profilerclass withmeasure()context managers for targeted timing of specific code blocks inopenmed/utils/profiling.py. - Global Sessions: Enable application-wide debugging with
enable_profiling()and retrieve results viaget_profile_report()without modifying function signatures throughout your codebase. - Automatic Decoration: Apply the
@profiledecorator to capture function-level timings transparently using the global profiler instance. - Ad-hoc Timing: Leverage
Timerandtimed()for lightweight, logging-friendly measurements during rapid debugging cycles. - Unified Reporting: All tools generate structured reports through
ProfileReport.format_report(), providing consistent visibility into model loading and inference performance.
Frequently Asked Questions
How do I enable profiling globally in an OpenMed application?
Call enable_profiling() at the start of your application to initialize the global profiler singleton in openmed/utils/profiling.py. This captures timings from any @profile decorators or explicit Profiler.measure() calls throughout your codebase. Retrieve the final report using get_profile_report() after your pipeline completes execution.
What is the difference between the Profiler class and the Timer utility?
The Profiler class accumulates multiple TimingResult objects into a comprehensive ProfileReport, making it suitable for benchmarking complete pipelines and comparing multiple operations. The Timer class provides single-shot measurements primarily for logging purposes, while the timed() context manager automatically logs elapsed time without accumulating results into a structured report.
Can I use the @profile decorator when the global profiler is disabled?
Yes, the decorator safely handles disabled states without raising errors. However, it will only record timing data when the global profiler is enabled via enable_profiling(). You do not need to remove the decorator when profiling is turned off—simply ensure enable_profiling() is called before the decorated functions execute to capture measurements.
Where are the profiling utilities tested in the OpenMed repository?
All profiling functionality is validated in tests/unit/test_profiling.py, which contains unit tests demonstrating the intended usage patterns for the Profiler class, global helper functions, @profile decorator, and Timer utilities. These tests verify that ProfileReport objects correctly aggregate timing results and that the global singleton behaves as expected across multiple import contexts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →