Skip to content

Commit 83bdcbd

Browse files
committed
add 2.5.0 to tested version
Signed-off-by: Victor Chang <[email protected]>
1 parent d93d4fc commit 83bdcbd

File tree

6 files changed

+148
-71
lines changed

6 files changed

+148
-71
lines changed
Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,62 @@
11
# NVIDIA NV-CLIP
22

3-
NV-CLIP is a multimodal embeddings model for image and text and this is a sample application that shows how to use the OpenAI SDK with NVIDIA Inference Microservice (NIM). Whether you are using a NIM from [build.nvidia.com/](https://build.nvidia.com/) or a self-hosted NIM, this sample application will work for both.
3+
NV-CLIP is a multimodal embeddings model for image and text, and this is a sample application that shows how to use the OpenAI SDK with NVIDIA Inference Microservice (NIM). Whether you are using a NIM from [build.nvidia.com/](https://build.nvidia.com/) or [a self-hosted NIM](https://docs.nvidia.com/nim/nvclip/latest/getting-started.html#option-2-from-ngc), this sample application will work for both.
44

5-
### Quick Start
5+
## Quick Start
66

7-
1. Add API key in `nvidia_nim.yaml`
7+
Get your [API Key](https://docs.nvidia.com/nim/nvclip/latest/getting-started.html#generate-an-api-key) and start the sample application.
8+
9+
1. Enter your API key in `nvidia_nim.yaml`
810
2. `./dev_container build_and_run nvidia_nim_nvclip`
911

10-
## Configuring the sample application
12+
## Advanced
13+
14+
### Configuring the sample application
1115

1216
Use the `nvidia_nim.yaml` configuration file to configure the sample application:
1317

14-
### Connection Information
18+
### NVIDIA-Hosted NV-CLIP NIM
19+
20+
By default, the application is configured to use NVIDIA-hosted NV-CLIP NIM.
1521

1622
```
1723
nim:
18-
base_url: https://integrate.api.nvidia.com/v1
19-
api_key:
24+
base_url: https://integrate.api.nvidia.com/v1
25+
api_key:
2026
2127
```
2228

23-
`base_url`: The URL of your NIM instance. Defaults to NVIDIA hosted NIMs.
24-
`api_key`: Your API key to access NVIDIA hosted NIMs.
29+
`base_url`: The URL of your NIM instance. Defaults to NVIDIA-hosted NIMs.
30+
`api_key`: Your API key to access NVIDIA-hosted NIMs.
2531

26-
## Run the sample application
2732

28-
There are a couple of options to run the sample application:
33+
Note: you may also configure your API key using an environment variable.
34+
E.g., `export API_KEY=...`
35+
36+
```bash
37+
# To use NVIDIA hosted NIMs available on build.nvidia.com, export your API key first
38+
export API_KEY=[enter your API key here]
39+
```
40+
2941

30-
### Run using Docker
42+
### Self-Hosted NIMs
3143

32-
To run the sample application with Docker, you must first build a Docker image that includes the sample application and its dependencies:
44+
To use a self-hosted NIM, refer to the [NV-CLIP](https://docs.nvidia.com/nim/nvclip/latest/getting-started.html) NIM documentation to configure and start the NIM.
45+
46+
Then, comment out the NVIDIA-hosted section and uncomment the self-hosted configuration section in the `nvidia_nim.yaml` file.
47+
48+
```bash
49+
nim:
50+
base_url: http://0.0.0.0:8000/v1/
51+
encoding_format: float
52+
api_key: NA
53+
model: nvidia/nvclip-vit-h-14
54+
```
55+
56+
57+
### Build The Application
58+
59+
To run the sample application, you must first build a Docker image that includes the sample application and its dependencies:
3360

3461
```
3562
# Build the Docker images from the root directory of Holohub
@@ -39,35 +66,49 @@ To run the sample application with Docker, you must first build a Docker image t
3966
Then, run the Docker image:
4067

4168
```bash
42-
./dev_container launch
69+
./dev_container launch
4370
```
4471

4572

46-
### Start the Application
73+
### Run the Application
4774

4875
To use the NIMs on [build.nvidia.com/](https://build.nvidia.com/), configure your API key in the `nvidia_nim.yaml` configuration file and run the sample app as follows:
4976

50-
note: you may also configure your api key using an environment variable.
51-
E.g., `export API_KEY=...`
52-
5377
```bash
54-
# To use NVIDIA hosted NIMs available on build.nvidia.com, export your API key first
55-
export API_KEY=[enter your api key here]
56-
5778
./run launch nvidia_nim_nvclip
5879
```
5980

60-
Have fun!
81+
## Using the Application
82+
83+
Once the application is ready, it will prompt you to input URLs to the images you want to perform inference.
84+
85+
```bash
86+
Enter a URL to an image: https://domain.to/my/image-cat.jpg
87+
Downloading image...
88+
89+
Enter a URL to another image or hit ENTER to continue: https://domain.to/my/image-rabbit.jpg
90+
Downloading image...
91+
92+
Enter a URL to another image or hit ENTER to continue: https://domain.to/my/image-dog.jpg
93+
Downloading image...
94+
95+
```
6196

97+
If there are no more images that you want to use, hit ENTER to continue and then enter a prompt:
6298

63-
## Connecting with Locally Hosted NIMs
99+
```bash
100+
Enter a URL to another image or hit ENTER to continue:
64101

65-
To use a locally hosted NIM, first download and start the NIM.
66-
Then configure the `base_url` parameter in the `nvidia_nim.yaml` configuration file to point to your local NIM instance.
102+
Enter a prompt: Which image contains a rabbit?
103+
```
67104

68-
The following example shows a NIM running locally and serving its APIs and the `meta-llama3-8b-instruct` model from `http://0.0.0.0:8000/v1`.
105+
The application will connect to the NIM to generate an answer and then calculate the cosine similarity between the images and the prompt:
69106

70107
```bash
71-
nim:
72-
base_url: http://0.0.0.0:8000/v1/
108+
⠧ Generating...
109+
Prompt: Which image contains a rabbit?
110+
Output:
111+
Image 1: 3.0%
112+
Image 2: 52.0%
113+
Image 3: 46.0%
73114
```

applications/nvidia_nim/nvidia_nim_nvclip/app.py

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,7 @@ def setup(self, spec: OperatorSpec):
6767
spec.input("in")
6868

6969
def compute(self, op_input, op_output, context):
70-
input = op_input.receive("in")
71-
72-
message = input[0].copy()
73-
message.append(input[1])
70+
message = op_input.receive("in")
7471

7572
# Reference: Cosine Similarity https://docs.nvidia.com/nim/nvclip/latest/getting-started.html#cosine-similarity
7673
# Calculate cosine similarity between images and text
@@ -93,7 +90,7 @@ def compute(self, op_input, op_output, context):
9390
f"Image {i+1}": round(float(d), 2) * 100 for i, d in enumerate(probabilities)
9491
}
9592

96-
print(f"\nPrompt: {input[1]}")
93+
print(f"\nPrompt: {message[-1]}")
9794
print("Output:")
9895
for prob in probabilities:
9996
print(f"{prob}: {probabilities[prob]}%")
@@ -114,9 +111,8 @@ def compute(self, op_input, op_output, context):
114111

115112

116113
class ExamplesOp(Operator):
117-
def __init__(self, fragment, *args, spinner, example, **kwargs):
114+
def __init__(self, fragment, *args, spinner, **kwargs):
118115
self.spinner = spinner
119-
self.example = example
120116

121117
# Need to call the base class constructor last
122118
super().__init__(fragment, *args, **kwargs)
@@ -126,37 +122,44 @@ def setup(self, spec: OperatorSpec):
126122

127123
def compute(self, op_input, op_output, context):
128124
user_images = []
129-
user_text = ""
130-
use_example = False
125+
user_prompt = ""
126+
131127
while True:
132-
print("\nEnter prompt or hit Enter to use default example: ", end="")
133-
user_input = sys.stdin.readline().strip()
134-
if user_input != "":
135-
user_text = user_input
128+
if len(user_images) == 0:
129+
print("\nEnter a URL to an image: ", end="")
136130
else:
137-
use_example = True
138-
user_images = self.example["images"]
139-
user_text = self.example["text"]
140-
break
131+
print("\nEnter a URL to another image or hit ENTER to continue: ", end="")
141132

142-
while True and not use_example:
143-
print("\nEnter URL to an image or hit Enter to send the request: ", end="")
144133
user_input = sys.stdin.readline().strip()
145134
if user_input == "":
146135
break
147-
user_images.append(self.pre_process_input(user_input))
136+
137+
image_data = self.pre_process_input(user_input)
138+
if image_data:
139+
user_images.append(image_data)
140+
141+
while True:
142+
print("\nEnter a prompt: ", end="")
143+
user_input = sys.stdin.readline().strip()
144+
if user_input != "":
145+
user_prompt = user_input
146+
break
148147

149148
self.spinner.start()
150-
op_output.emit((user_images, user_text), "out")
149+
150+
message = user_images + [user_prompt]
151+
152+
op_output.emit(message, "out")
151153

152154
def pre_process_input(self, data):
153155
prepared_request = PreparedRequest()
154156
try:
155157
prepared_request.prepare_url(data, None)
156158
print("Downloading image...")
157159
return base64.b64encode(requests.get(prepared_request.url).content).decode("utf-8")
158-
except Exception:
159-
return data
160+
except Exception as e:
161+
logger.error("Error downloading image: %s", str(e))
162+
return None
160163

161164

162165
class NVClipNIMApp(Application):
@@ -173,7 +176,6 @@ def compose(self):
173176
self,
174177
name="input",
175178
spinner=spinner,
176-
example=self.kwargs("example"),
177179
)
178180
chat_op = OpenAIOperator(
179181
self,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# For usage and instructions, visit NV-CLIP at https://docs.nvidia.com/nim/nvclip/
18+
19+
# Choose a container name for bookkeeping
20+
export CONTAINER_NAME=nvclip
21+
22+
# The container name from the previous ngc registry image list command
23+
Repository=nvclip
24+
Latest_Tag=1.0.0
25+
26+
# Choose a NV-CLIP NIM Image from NGC
27+
export IMG_NAME="nvcr.io/nim/nvidia/${Repository}:${Latest_Tag}"
28+
29+
# Choose a path on your system to cache the downloaded models
30+
export LOCAL_NIM_CACHE=~/.cache/nim
31+
mkdir -p "$LOCAL_NIM_CACHE"
32+
33+
# Start the NV-CLIP NIM
34+
docker run -it --rm --name=$CONTAINER_NAME \
35+
--runtime=nvidia \
36+
--gpus all \
37+
-e NGC_API_KEY=$NGC_API_KEY \
38+
-v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \
39+
-u $(id -u) \
40+
-p 8000:8000 \
41+
$IMG_NAME

applications/nvidia_nim/nvidia_nim_nvclip/metadata.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"minimum_required_version": "1.0.3",
1717
"tested_versions": [
1818
"1.0.3",
19-
"2.1.0"
19+
"2.1.0",
20+
"2.5.0"
2021
]
2122
},
2223
"platforms": [

applications/nvidia_nim/nvidia_nim_nvclip/nvidia_nim.yaml

Lines changed: 9 additions & 15 deletions
Large diffs are not rendered by default.

run

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,7 @@ lint() {
469469
# Fix python black code formatting issues, run:
470470
run_command black ${DIR_TO_RUN} || exit_code=1
471471
run_command codespell -w -i 3 ${DIR_TO_RUN} --ignore-words codespell_ignore_words.txt \
472-
--skip="*.onnx,*.min.js,*.min.js.map,Contrastive_learning_Notebook.ipynb,./data" \
473-
--skip="./applications/nvidia_nim/nvidia_nim_nvclip/nvidia_nim.yaml" || exit_code=1
472+
--skip="*.onnx,*.min.js,*.min.js.map,Contrastive_learning_Notebook.ipynb,./data" || exit_code=1
474473

475474
# Fix cpplint with clang
476475
files_to_fix=`set -o pipefail; ${HOLOHUB_PY_EXE} -m cpplint \
@@ -516,7 +515,6 @@ lint() {
516515

517516
echo "Code spelling"
518517
run_command codespell $DIR_TO_RUN --skip="*.onnx,*.min.js,*.min.js.map,Contrastive_learning_Notebook.ipynb,./data" \
519-
--skip="./applications/nvidia_nim/nvidia_nim_nvclip/nvidia_nim.yaml" \
520518
--ignore-words codespell_ignore_words.txt \
521519
--exclude-file codespell.txt || exit_code=1
522520

0 commit comments

Comments
 (0)