-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathngc.py
More file actions
174 lines (157 loc) · 7.16 KB
/
Copy pathngc.py
File metadata and controls
174 lines (157 loc) · 7.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# --------------------------------
# Please keep distribution of this code to NVIDIA and partners only
# --------------------------------
# EXAMPLE CODE TO GET NGC API KEY FROM NTS
# This script demonstrates how to get an NGC API key using the NVIDIA GPU Cloud (NGC) Token Service.
# The script uses either nvidia-smi or pynvml library to get the GPU device information
# This device info is sent to an NVIDIA service for validation to exchange for a token
#
# WARNING - this is only sample code please do not use in production, just as an reference
#
# NOTE - plan to update your client code once PDI is available in NVML and nvidia-smi
# for now the example will hash a UUID into a pdi-like 64 bit hex string
import re
import subprocess
import pynvml as nvml
import requests
def get_device_info_nvml():
try:
nvml.nvmlInit()
deviceCount = nvml.nvmlDeviceGetCount()
deviceInfo = []
for i in range(deviceCount):
handle = nvml.nvmlDeviceGetHandleByIndex(i)
uuid = nvml.nvmlDeviceGetUUID(handle)
name = nvml.nvmlDeviceGetName(handle)
brand = nvml.nvmlDeviceGetBrand(handle)
architecture = nvml.nvmlDeviceGetArchitecture(handle)
pciDeviceId = nvml.nvmlDeviceGetPciInfo(handle).pciDeviceId
pciDeviceId_64bit = format(pciDeviceId, 'X')
# pdi = 'Unknown' # nvml.nvmlDeviceGetPDI(handle) # TODO - PDI is not available in NVML API yet
fakePdi = int(hash(uuid) % 2**64) # hash the uuid to a 16 bit integer
pdi = fakePdi # TODO - just until PDI is available in NVML API
pdi_64bit = format(pdi, 'X')
# Map brand and architecture to human-readable strings
# brand_str = get_brand_name(brand)
# architecture_str = get_architecture_name(architecture)
deviceInfo.append({
'uuid': uuid,
'pdi': f"0x{pdi_64bit}",
'name': name,
'brand': brand,
'architecture': architecture,
'pci_device_id': f"0x{pciDeviceId_64bit}",
})
nvml.nvmlShutdown()
print("NVML device info:")
print(deviceInfo)
return deviceInfo
except nvml.NVMLError as e:
print(f"NVML Error: {e}")
nvml.nvmlShutdown()
return []
def get_device_info_smi():
try:
output = subprocess.check_output(['nvidia-smi', '-q'], text=True)
deviceInfo = []
uuid_pattern = re.compile(r"GPU UUID\s*:\s*(.+)")
pdi_pattern = re.compile(r"PDI\s*:\s*(.+)")
name_pattern = re.compile(r"Product Name\s*:\s*(.+)")
brand_pattern = re.compile(r"Product Brand\s*:\s*(.+)")
arch_pattern = re.compile(r"Product Architecture\s*:\s*(.+)")
pci_pattern = re.compile(r"Device Id\s*:\s*(.+)")
matches = {
"uuid": uuid_pattern.search(output),
"pdi": pdi_pattern.search(output),
"name": name_pattern.search(output),
"brand": brand_pattern.search(output),
"architecture": arch_pattern.search(output),
"pci_device_id": pci_pattern.search(output),
}
# TODO - just until PDI is available in NVML API
if not matches["pdi"]:
fakePdi = int(hash(matches["uuid"].group(1).strip()) % 2**64) # hash the uuid to a 16 bit integer for testing
pdi_64bit = format(fakePdi, 'X')
matches["pdi"] = re.match(r"(.+)", f"0x{pdi_64bit}")
deviceInfo.append({k: (m.group(1).strip() if m else "Unknown") for k, m in matches.items()})
print("SMI device info:")
print(deviceInfo)
return deviceInfo
except subprocess.CalledProcessError as e:
print(f"nvidia-smi error: {e}")
return []
def validate_device_info(deviceInfo):
matchInName = ['RTX', 'OTHER DEVICE NAME TEST']
for device in deviceInfo:
if any(keyword in device.get('name', '') for keyword in matchInName):
print(f"Valid device name {device['name']} found")
return True
matchInBrandString = ['GeForce','5']
for device in deviceInfo:
if any(keyword in str(device.get('brand', '')) for keyword in matchInBrandString):
print(f"Valid device brand {device['brand']} found")
return True
print("No valid device found in the list")
return False
def get_ngc_key_from_device_info(deviceInfo):
# Optional - check env for vars
# if NGC_API_KEY or NGC_CLI_API_KEY decide if the client should use that instead
# the key will still need to be setup properly with Catalog Access, and the owner will need an NVAIE sub # noqa: E501
# or be a member of the NVIDIA developer program (https://developer.nvidia.com/developer-program)
# apiKey = os.environ.get('NGC_API_KEY')
# if apiKey:
# print("Using the API key from the environment variable instead of calling API") # noqa: E501
# return apiKey
ngcKeyServiceUrl = 'https://nts.ngc.nvidia.com/v1/token'
payload = {
"client_id": "comfyui",
"pdi": deviceInfo[0].get('pdi', 'Unknown') if deviceInfo else 'Unknown',
"access_policy_name": "nim-dev",
"device": deviceInfo[0] if deviceInfo else {}
}
print(f"debug Payload: {payload}")
try:
response = requests.post(ngcKeyServiceUrl, headers={'Accept': 'application/json'}, json=payload) # noqa: E501
print(f"Response: {response}")
response.raise_for_status()
keyData = response.json()
print(f"Key data: {keyData}")
return keyData.get('access_token')
except requests.RequestException as e:
print(f"Error fetching API key: {e}")
return None
def get_ngc_key():
# two different examples of getting device info
# note: branch/architecture, nvidia-smi gives strings, NVML gives ints
deviceInfoNvml = get_device_info_nvml()
deviceInfoSmi = get_device_info_smi()
# client check option - TBD if needed by client development team
# if not validate_device_info(deviceInfoNvml):
# print("Device info validation failed - exiting")
# exit(1)
key = get_ngc_key_from_device_info(deviceInfoNvml)
if key:
print(f"Key: {key}")
return key
else:
raise Exception("Error getting NGC API key. Please follow the instructions in the README to set up your NGC API key.") # noqa: E501
if __name__ == "__main__":
# deviceInfoNvml = get_device_info_nvml()
# deviceInfoSmi = get_device_info_smi()
# assert deviceInfoNvml[0]["pdi"] == deviceInfoSmi[0]["pdi"]
# key = get_ngc_key_from_device_info(deviceInfoSmi)
get_ngc_key()