Observing a Workflow with NVIDIA Data Flywheel#
This guide provides a step-by-step process to enable observability in a NVIDIA NeMo Agent toolkit workflow that exports runtime traces to an Elasticsearch instance that is part of the NVIDIA Data Flywheel Blueprint. The Data Flywheel Blueprint can then leverage the traces to fine-tune and evaluate smaller models which can be deployed to replace the original model to reduce latency.
The Data Flywheel integration supports LangChain/LangGraph based workflows with nim and openai LLM providers and can be enabled with just a few lines of configuration.
Supported Framework and Provider Combinations#
The Data Flywheel integration currently supports LangChain (as used in LangChain pipelines and LangGraphs) with the following LLM providers:
_type: openai- OpenAI provider_type: nim- NVIDIA NIM provider
The integration captures LLM_START events for completions and tool calls when using these specific combinations. Other framework and provider combinations are not currently supported.
Step 1: Prerequisites#
Before using the Data Flywheel integration, ensure you have:
NVIDIA Data Flywheel Blueprint deployed and configured
Valid Elasticsearch credentials (username and password)
Step 2: Install the Data Flywheel Plugin#
To install the Data Flywheel plugin, run the following:
uv pip install -e '.[data-flywheel]'
Step 3: Modify Workflow Configuration#
Update your workflow configuration file to include the Data Flywheel telemetry settings:
general:
telemetry:
tracing:
data_flywheel:
_type: data_flywheel_elasticsearch
client_id: my_nat_app
index: flywheel
endpoint: ${ELASTICSEARCH_ENDPOINT}
username: elastic
password: elastic
batch_size: 10
This configuration enables exporting trace data to NVIDIA Data Flywheel via Elasticsearch.
Configuration Parameters#
The Data Flywheel integration supports the following core configuration parameters:
Parameter |
Description |
Required |
Example |
|---|---|---|---|
|
Identifier for your NAT application to distinguish traces between deployments |
Yes |
|
|
Elasticsearch index name where traces will be stored |
Yes |
|
|
Elasticsearch endpoint URL |
Yes |
|
|
Elasticsearch username for authentication |
No |
|
|
Elasticsearch password for authentication |
No |
|
|
Size of batch to accumulate before exporting |
No |
|
Step 4: Run Your Workflow#
Run your workflow using the updated configuration file:
nat run --config_file config-data-flywheel.yml --input "Your workflow input here"
Step 5: Monitor Trace Export#
As your workflow runs, traces will be automatically exported to Elasticsearch in batches. You can monitor the export process through the NeMo Agent toolkit logs, which will show information about successful exports and any errors.
Step 6: Access Data in Data Flywheel#
Once traces are exported to Elasticsearch, they become available in the NVIDIA Data Flywheel system for:
LLM distillation and optimization
Performance analysis and monitoring
Training smaller, more efficient models
Runtime optimization insights
Advanced Configuration#
Workload Scoping#
The Data Flywheel integration uses workload identifiers to organize traces for targeted model optimization. Understanding how to scope your workloads correctly is crucial for effective LLM distillation.
Default Scoping Behavior#
By default, each trace receives a Data Flywheel workload_id that maps to the parent NeMo Agent toolkit registered function. The combination of client_id and workload_id is used by Data Flywheel to select data as the basis for training jobs.
Custom Scoping with @track_unregistered_function#
For fine-grained optimization, you can create custom workload scopes using the @track_unregistered_function decorator. This is useful when a single registered function contains multiple LLM invocations that would benefit from separate model optimizations.
from nat.profiler.decorators.function_tracking import track_unregistered_function
@track_unregistered_function(name="document_summarizer", metadata={"task_type": "summarization"})
def summarize_document(document: str) -> str:
return llm_client.complete(f"Summarize: {document}")
@track_unregistered_function(name="question_answerer")
def answer_question(context: str, question: str) -> str:
return llm_client.complete(f"Context: {context}\nQuestion: {question}")
The decorator supports:
name: Customworkload_id(optional, defaults to function name)metadata: Additional context for traces (optional)
Resources#
For more information about NVIDIA Data Flywheel: