Quickstart Guide#
Downloading the NIM#
Download the Semantic Split C-RADIO NIM image with the following command.
docker pull \
nvcr.io/nim/nvidia/nv-semantic-split-cradio:latest
Note
The NIM image is 11.82 GB and the download time depends on your internet connection speed.
Prepare External Data Mounts for I/O#
The Semantic Split C-RADIO NIM works with both data stored locally and data available in a S3 bucket. This NIM provides functionality to download the data from a S3 bucket and upload the output to S3 bucket.
See this table Supported Operation Modes for information on supported operation modes.
This NIM requires mounting at-least two external folders (i.e. folders existing outside of the NIM) at the following two required locations inside the NIM:
/nv_scratch_space: This location inside the NIM is the workspace where all artifacts will be written to./opt/nim/cache: This location inside the NIM is used to store various files needed by the NIM that are downloaded and cached on the first run of the NIM.
For the operational mode where outputs are to be stored on local file system, NIM requires mounting the folder at the following recommended location inside the NIM:
/results: This location inside the NIM is the root where all results will be written to.
For the operational mode where inputs are stored on local file system, NIM requires mounting the folder at the following recommended location inside the NIM:
/data: This location inside the NIM is the root where all input data will be accessed from.
Set the Ownership of Data Mounts#
The Semantic Split C-RADIO NIM image uses the user-id 1000. To make sure the external data mounts for the cache, the data, and the results work properly inside the NIM, you must change the user and group of those folders and then use them for mounting in the docker command. Use the following commands on the host system where the NIM is supposed to launch, before launching it, to set the folder access permissions:
sudo chown -R 1000:1000 /path/to/data/folder/on/host
sudo chown -R 1000:1000 /path/to/scratch/space/on/host
sudo chown -R 1000:1000 /path/to/results/folder/on/host
sudo chown -R 1000:1000 /path/to/cache/folder/on/host
Launch the NIM#
After modifying use the following command to launch the Semantic Split C-RADIO NIM:
export NGC_API_KEY=<NGC API Key>
docker run --rm --runtime=nvidia --gpus device=<GPU ID> --shm-size 2g \
-p 8000:8000 -e NGC_API_KEY \
-e S3_ENDPOINT_URL='<S3 Endpoint URL>' \
-e S3_TEAM_NAME='<S3 Team name>' \
-e S3_ACCESS_KEY='<S3 Access Key>' \
-e S3_REGION_NAME='<S3 Region Name>' \
-e NV_SCRATCH_SPACE=/nv_scratch_space \
-v /path/to/data/folder/on/host:/data \
-v /path/to/scratch/space/on/host:/nv_scratch_space:rw \
-v /path/to/results/folder/on/host:/results:rw \
-v /path/to/cache/folder/on/host:/opt/nim/.cache \
-t nvcr.io/nim/nvidia/nv-semantic-split-cradio:latest
To enable S3 support, you must pass all the S3 related environment variables.
If NIM is operating in local file system only mode, then you can omit S3 related environment variables.
After the NIM is running, you should see an output similar to the following:
"timestamp": "2024-12-12 01:38:15,688", "level": "INFO", "message": "Serving endpoints:
0.0.0.0:8000/v1/health/live (GET)
0.0.0.0:8000/v1/health/ready (GET)
0.0.0.0:8000/v1/metrics (GET)
0.0.0.0:8000/v1/license (GET)
0.0.0.0:8000/v1/metadata (GET)
0.0.0.0:8000/v1/manifest (GET)
0.0.0.0:8000/video_split (POST)"
"timestamp": "2024-12-12 01:38:15,688", "level": "INFO", "message": "{'message': 'Starting HTTP Inference server', 'port': 8000, 'workers_count': 1, 'host': '0.0.0.0', 'log_level': 'info', 'SSL': 'disabled'}"
Check the NIM’s Health#
Leave the current terminal open with the NIM running, open a new terminal, and use the following methods to query the health check end-point. This might take a couple of minutes.
Invoke By Using cURL#
curl -X 'GET' \
'http://localhost:8000/v1/health/ready' \
-H 'accept: application/json'
Expected Result if the NIM’s health is good:
{"description":"Triton readiness check","status":"ready"}
Invoke By Using Python#
import requests
r = requests.get("http://localhost:8000/v1/health/ready")
if r.status_code == 200:
print("NIM is healthy!")
else:
print("NIM is not ready!")
Expected Result if the NIM’s health is good:
NIM is healthy!
Submit a Video Splitting Request#
The endpoint to split videos is /video_split, and it takes the following two body parameters:
input_paths- A list of paths to the raw videos.These paths should be relative to the mount point
/dataThe request must be formatted to the expected input data json format.
results_dir- a directory inside the NIM that points towards the folder where you want to store the transcoded output videos. This should be relative to the mount point/results
There is a delay between when the NIM is started, and when it becomes ready to receive video split requests. Before you submit a video split request, check the health of the NIM to ensure that it is ready.
This is a blocking synchronous request. Results are only returned after all the videos are processed successfully. If the pipeline fails for any reason, a 500 internal server error message is returned. NIM health should be confirmed as healthy before making additional requests.
Invoke By Using cURL#
curl -s -X POST -H 'Content-Type: application/json' http://0.0.0.0:8000/video_split \
--data '{
"input_paths": [
"/data/path/to/input1.mp4",
"/data/path/to/input2.mp4",
...
"/data/path/to/inputN.mp4",
],
"results_dir": "/results"
}'
To process an input file from a S3 bucket, you should pass a S3 URL.
To save the output in a S3 bucket, you should pass the bucket name as "results_dir": s3://<bucket name>.
Script to generate curl request#
You can use the following bash script to generate a pre-formatted curl video splitting request provided that the following is true:
The data folder on the host machine contains only valid input video files.
How to call:
generate_json_request.sh <data folder on host machine> | tee json_request.sh
generate_request.sh
#!/bin/bash
readarray -t video_files < <(ls $1)
echo 'curl -s -X POST -H 'Content-Type: application/json' http://0.0.0.0:8000/video_split \'
echo '--data '"'{"
echo ' "input_paths": ['
for (( i=0; i<${#video_files[@]}-1; i++ )); do
echo '"/data/'${video_files[i]}'"',
done
echo '"/data/'"${video_files[-1]}"'"'
echo ' ],'
echo ' "results_dir": "/results"'
echo " }' "
Invoke By Using Python#
import requests
import json
import time
# Define the URL and the header
url = 'http://0.0.0.0:8000/video_split'
headers = {'Content-Type': 'application/json'}
# Define the data payload
data = {
"input_paths": [
"/data/path/to/input1.mp4",
"/data/path/to/input2.mp4",
...,
"/data/path/to/inputN.mp4"
],
"results_dir": "/results/test_1/"
}
# Convert the data to JSON format
json_data = json.dumps(data)
start_time = time.time()
# Make the POST request
response = requests.post(url, headers=headers, data=json_data)
# Check if the response was successful
if response.status_code == 200:
# Parse the JSON response
response_data = response.json()
# Print the parsed data (or handle it as needed)
print(response_data)
end_time = time.time()
throughput = response_data['total_frames_processed']/(end_time - start_time)
print(f"Throughput: {throughput:0.2f} FPS")
else:
print(f"Failed to get a successful response: {response.status_code}")
print(response.text)
For complete documentation of the API specification of the Semantic Split C-Radio NIM, see API Reference.
Get Video Splitting Results#
After a successful run of the video splitting pipeline, a JSON response consisting of various details about the results is returned by the video_split request. The JSON has the following structure:
int: total_frames_processed : a count of all the frames processed in this run so far
int: total_output_frames : a count of all the frames in the output clips generated by the pipeline
dict: result
keys are the path of the video
values are a dictionary consisting of
int: num_clips
list[dict]: clip
int: clip_span with start and end index
str: clip path
{
"total_frames_processed": 7351,
"total_output_frames": 2194,
"results": {
"/data/path/to/input1.mp4": {
"num_clips": 5,
"clips": [
{
"span": {
"start_frame_idx": 82,
"end_frame_idx": 744
},
"path": "/results/test_1/input1_000082_000744.mp4"
},
{
"span": {
"start_frame_idx": 1530,
"end_frame_idx": 1931
},
"path": "/results/test_1/input1_001530_001931.mp4"
},
{
"span": {
"start_frame_idx": 2006,
"end_frame_idx": 2220
},
"path": "/results/test_1/input1_002006_002220.mp4"
}
]
}
}
}