Skip to content

added autonomous lab telco example #292

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "16b65cd9-dcb9-4b32-b7ac-ae152db55c00",
"metadata": {},
"source": [
"### Automate 5G Network Configurations with NVIDIA AI LLM Agents and Kinetica Accelerated Database"
]
},
{
"cell_type": "markdown",
"id": "b08157d5-eeea-463b-927b-10792da54d18",
"metadata": {},
"source": [
"This DLI introduces an Agentic Generative AI solution designed to address bandwidth allocation challenges in 5G networks. It is divided into two parts that guide you through setting up and managing a 5G network."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "64f0e900-6e16-4054-b124-820a5dae11eb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Cloning into 'autonomous_5g_slicing_lab'...\n",
"remote: Enumerating objects: 9025, done.\u001b[K\n",
"remote: Counting objects: 100% (9025/9025), done.\u001b[K\n",
"remote: Compressing objects: 100% (4230/4230), done.\u001b[K\n",
"remote: Total 9025 (delta 4692), reused 8969 (delta 4650), pack-reused 0 (from 0)\u001b[K\n",
"Receiving objects: 100% (9025/9025), 33.87 MiB | 55.32 MiB/s, done.\n",
"Resolving deltas: 100% (4692/4692), done.\n"
]
}
],
"source": [
"!git clone https://github.com/acanaveras/autonomous_5g_slicing_lab.git\n"
]
},
{
"cell_type": "markdown",
"id": "7eb5c629-44da-4d33-97d0-40717c65c6a6",
"metadata": {},
"source": [
"Insert your API Key in the next cell to get it stored for the application"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "fffa0783-c270-4ed6-9b4b-1f5040341f4f",
"metadata": {},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"Enter your API Key: ········\n"
]
},
{
"ename": "FileNotFoundError",
"evalue": "[Errno 2] No such file or directory: '/autonomous_5g_slicing_lab/agentic-llm/config.yaml'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[2], line 25\u001b[0m\n\u001b[1;32m 22\u001b[0m config[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mAPI_KEY\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m api_key\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Write the updated configuration back to the YAML file\u001b[39;00m\n\u001b[0;32m---> 25\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28;43mopen\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43myaml_path\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mw\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m file:\n\u001b[1;32m 26\u001b[0m yaml\u001b[38;5;241m.\u001b[39msafe_dump(config, file)\n\u001b[1;32m 28\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m✅ API Key successfully saved to config.yaml\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
"File \u001b[0;32m/usr/local/lib/python3.10/dist-packages/IPython/core/interactiveshell.py:324\u001b[0m, in \u001b[0;36m_modified_open\u001b[0;34m(file, *args, **kwargs)\u001b[0m\n\u001b[1;32m 317\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m file \u001b[38;5;129;01min\u001b[39;00m {\u001b[38;5;241m0\u001b[39m, \u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m2\u001b[39m}:\n\u001b[1;32m 318\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 319\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIPython won\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mt let you open fd=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfile\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m by default \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 320\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mas it is likely to crash IPython. If you know what you are doing, \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 321\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124myou can use builtins\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m open.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 322\u001b[0m )\n\u001b[0;32m--> 324\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mio_open\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfile\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
"\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: '/autonomous_5g_slicing_lab/agentic-llm/config.yaml'"
]
}
],
"source": [
"import yaml\n",
"from getpass import getpass\n",
"from pathlib import Path\n",
"\n",
"# Prompt for API Key securely (input not shown)\n",
"api_key = getpass(\"Enter your API Key: \")\n",
"\n",
"# Define the path to the YAML file\n",
"yaml_path = Path(\"./autonomous_5g_slicing_lab/agentic-llm/config.yaml\")\n",
"\n",
"# Read existing YAML if it exists, otherwise start fresh\n",
"if yaml_path.exists():\n",
" with open(yaml_path, 'r') as file:\n",
" try:\n",
" config = yaml.safe_load(file) or {}\n",
" except yaml.YAMLError:\n",
" config = {}\n",
"else:\n",
" config = {}\n",
"\n",
"# Insert or update the API_KEY\n",
"config['API_KEY'] = api_key\n",
"\n",
"# Write the updated configuration back to the YAML file\n",
"with open(yaml_path, 'w') as file:\n",
" yaml.safe_dump(config, file)\n",
"\n",
"print(\"✅ API Key successfully saved to config.yaml\")\n"
]
},
{
"cell_type": "markdown",
"id": "a77a79b9-644e-4b4f-b781-ea6810a99980",
"metadata": {},
"source": [
"### Agentic LLMs for 5G Section\n",
"\n",
"Once you have the **5G Lab GitHub** repository cloned, you can proceed to the **Agentic LLMs** section. This part of the lab demonstrates how to deploy an agentic workflow to monitor network performance and dynamically adjust bandwidth allocation.\n",
"\n",
"- **Part A – Setup of 5G Lab environment** \n",
" Located at: `./autonomous5g_slicing_lab/llm-slicing-5g-lab/DLI_Lab_Setup.ipynb` \n",
" Provides instructions to set up a 5G Network Software Stack in your environemnt.\n",
"\n",
"- **Part B – 5G Network Agent Workflow** \n",
" Located at: `./autonomous5g_slicing_lab/agentic-llm/agentic_pipeline_DLI.ipynb` \n",
" Explains the agentic pipeline in **LangGraph** for managing 5G network slicing and bandwidth allocation.\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
10 changes: 10 additions & 0 deletions community/autonomous_5g_slicing_lab/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Agentic LLMs for 5G Section
Once you have the 5G Lab GitHub repository cloned, you can proceed to the Agentic LLMs section. This part of the lab demonstrates how to deploy an agentic workflow to monitor network performance and dynamically adjust bandwidth allocation.

Part A – Setup of 5G Lab environment
Located at: ./autonomous5g_slicing_lab/llm-slicing-5g-lab/DLI_Lab_Setup.ipynb
Provides instructions to set up a 5G Network Software Stack in your environemnt.

Part B – 5G Network Agent Workflow
Located at: ./autonomous5g_slicing_lab/agentic-llm/agentic_pipeline_DLI.ipynb
Explains the agentic pipeline in LangGraph for managing 5G network slicing and bandwidth allocation.
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Nvidia Logo](./images/nvidia.png) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5G Network Configuration Agent\n",
"\n",
"### Overview \n",
"This notebook outlines how the 5G network configuration works—how it detects SDU buffer full errors and reconfigures the network. We will use concepts demonstrated in [intro_agents.ipynb](intro_agents.ipynb) to build this agent using LangGraph and LangChain.\n",
"\n",
"### Table of Contents\n",
"1. Architecture Overview\n",
"2. File Descriptions\n",
"3. Define and run the Agent\n",
"4. Streamlit UI implementation\n",
"\n",
"### 1. Architecture Overview\n",
"\n",
"![Architecture diagram](./images/architecture_diagram.png) \n",
"\n",
"#### Key Components: \n",
"\n",
"**Agents**:\n",
"1. **Monitoring Agent**: \n",
" - Continuously reads gNodeB logs from `../llm-slicing-5g-lab/logs/gNodeB.log`. \n",
" - Analyzes each chunk for SDU buffer full errors. \n",
" - Routes to the Configuration Agent if an error is detected. \n",
"\n",
"2. **Configuration Agent**: \n",
" - Called when an error is detected in the gNodeB logs. \n",
" - Has two tools bound to it: `get_packet_loss` and `reconfigure_network`. \n",
" - First, retrieves the latest packet loss logs from the database using the `get_packet_loss` tool. \n",
" - Analyzes the logs and determines which UE needs more bandwidth. Based on this, it assigns higher bandwidth to the selected UE. \n",
" - Calls the `reconfigure_network` tool to use xAPP and reconfigure the network. \n",
" - Returns control to the Monitoring Agent to continue monitoring. \n",
"\n",
"**Tools**:\n",
"1. **`get_packet_loss`**: Queries the database and retrieves a DataFrame containing per-UE packet loss statistics. \n",
"2. **`reconfigure_network`**: Calls the xAPP with optimized slicing parameters to adjust network configurations. \n",
"\n",
"#### Example Error Logs \n",
"\n",
"```md\n",
"[RLC] /home/nvidia/llm-slicing-5g-lab/openairinterface5g/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c:1769:nr_rlc_entity_am_recv_sdu: warning: 195 SDU rejected, SDU buffer full\n",
" [NR_MAC] Frame.Slot 896.0\n",
" UE RNTI c1f9 CU-UE-ID 1 in-sync PH 0 dB PCMAX 0 dBm, average RSRP -44 (16 meas)\n",
" UE c1f9: UL-RI 1, TPMI 0\n",
" UE c1f9: dlsch_rounds 23415/1/0/0, dlsch_errors 0, pucch0_DTX 0, BLER 0.00000 MCS (0) 28\n",
" UE c1f9: ulsch_rounds 8560/0/0/0, ulsch_errors 0, ulsch_DTX 0, BLER 0.00000 MCS (0) 9\n",
" UE c1f9: MAC: TX 177738642 RX 612401 bytes\n",
" UE c1f9: LCID 1: TX 1022 RX 325 bytes\n",
"```\n",
" \n",
"### 2. Files to Refer \n",
"\n",
"- **[agents.py](./agents.py)** – Contains code for Monitoring and Configuration Agents. \n",
"- **[tools.py](./tools.py)** – Implements the tools used by the agents. \n",
"- **[langgraph_agent.py](./langgraph_agent.py)** – Defines the LangGraph agent workflow. \n",
"- **[chatbot_DLI.py](./chatbot_DLI.py)** – Implementation for the Streamlit UI. \n",
"\n",
"\n",
"#### Expected Output \n",
"\n",
"By the end of this notebook, you will have: \n",
"- A functional LangGraph workflow connected to the 5g slicing lab, that detects network issues and triggers reconfiguration. \n",
"- A pipeline capable of analyzing logs, querying packet loss data, and adjusting slicing parameters dynamically. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating a LangGraph Workflow "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We have defined two agents—the **Monitoring Agent** and the **Configuration Agent**—as combinations of a model and the tool(s) they have access to. This is achieved using LangGraph's `create_react_agent()` function, which creates an agent that employs ReAct prompting.\n",
"\n",
"**States in Graph** \n",
" - A state represents the evolving context of execution, maintaining data across multiple steps. \n",
" - It stores intermediate results, tool outputs, and agent decisions. \n",
" - States enable reasoning over past interactions, ensuring continuity in the workflow. \n",
"\n",
"**Nodes and Edges in LangGraph** \n",
" - **Nodes** represent agents, tool calls, or decision steps in the workflow. \n",
" - **Edges** define the flow between nodes, determining execution order based on conditions. \n",
" - This structure allows dynamic decision-making and parallel execution where needed. \n",
"\n",
"Refer [this](https://langchain-ai.github.io/langgraph/concepts/low_level/) for more information.\n",
"\n",
"The workflow has been defined in [langgraph_agent.py](langgraph_agent.py), please refer it for implementation details. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Running the Streamlit User Interface\n",
"\n",
"We provide a predefined Streamlit-based user interface for monitoring the system in real time. This interface allows users to interact with the monitoring software efficiently and gain insights into its operation.\n",
"\n",
"#### About Streamlit:\n",
"[Streamlit](https://streamlit.io/) is a lightweight Python framework for building interactive web applications with minimal effort. It enables users to create and deploy data-driven dashboards and tools using simple Python scripts.\n",
"\n",
"#### Features of the UI:\n",
"- Real-time Log Monitoring – View live logs generated by the agent.\n",
"- Packet Loss Visualization – Monitor real-time packet loss of UE1 and UE2 using dynamic charts.\n",
"- Agent Control – Start and stop the agent directly through the UI."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"var url = 'http://'+window.location.host+'/dashboard';\n",
"element.innerHTML = '<a style=\"color:#76b900;\" target=\"_blank\" href='+url+'><h2>< Link To Streamlit Frontend ></h2></a>';\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%js\n",
"var url = 'http://'+window.location.host+'/dashboard';\n",
"element.innerHTML = '<a style=\"color:#76b900;\" target=\"_blank\" href='+url+'><h2>< Link To Streamlit Frontend ></h2></a>';"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Collecting usage statistics. To deactivate, set browser.gatherUsageStats to false.\n",
"\u001b[0m\n",
"\u001b[0m\n",
"\u001b[34m\u001b[1m You can now view your Streamlit app in your browser.\u001b[0m\n",
"\u001b[0m\n",
"\u001b[34m Local URL: \u001b[0m\u001b[1mhttp://localhost:8501\u001b[0m\n",
"\u001b[34m Network URL: \u001b[0m\u001b[1mhttp://172.27.19.176:8501\u001b[0m\n",
"\u001b[34m External URL: \u001b[0m\u001b[1mhttp://204.52.26.81:8501\u001b[0m\n",
"\u001b[0m\n"
]
}
],
"source": [
"!~/.local/bin/streamlit run chatbot_DLI.py --server.enableCORS=false --server.enableXsrfProtection=false"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Running Langgraph Agent"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The streamlit UI calls langgraph_agent.py in the background. The agent logs its outputs to agent.log, which are in turn displayed on the UI. You may run the script to see how the agent works. Log files are written to in the `/llm-slicing-5g-lab/logs` directory. Run the following commands in separate terminals to stream logs for agent, UE1 and UE2 respectively.\n",
"\n",
"```sh\n",
"tail -f /llm-slicing-5g-lab/logs/agent.log\n",
"tail -f /llm-slicing-5g-lab/logs/UE2_iperfc.log\n",
"tail -f /llm-slicing-5g-lab/logs/UE1_iperfc.log\n",
"```\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!python3 langgraph_agent.py"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Loading