NVIDIA Earth-2 FourCastNet NIM 快速入门指南#
使用本文档开始使用 NVIDIA Earth-2 FourCastNet NIM。
重要提示
在您可以使用本文档之前,您必须满足所有前提条件。
启动 NIM#
使用以下命令拉取 NIM 容器。
注意
容器大小约为 34GB(未压缩),下载时间取决于互联网连接速度。
docker pull nvcr.io/nim/nvidia/fourcastnet:1.0.0
使用以下命令运行 NIM 容器。此命令启动 NIM 容器并公开端口 8000,供用户与 NIM 交互。它将模型拉取到本地文件系统上。
注意
模型大小约为 6GB,下载时间取决于互联网连接速度。
export NGC_API_KEY=<NGC API Key> docker run --rm --runtime=nvidia --gpus all --shm-size 4g \ -p 8000:8000 \ -e NGC_API_KEY \ -t nvcr.io/nim/nvidia/fourcastnet:1.0.0
NIM 运行后,验证您是否看到类似于以下的输出
I0829 05:18:42.152983 108 grpc_server.cc:2466] "Started GRPCInferenceService at 0.0.0.0:8001" I0829 05:18:42.153277 108 http_server.cc:4638] "Started HTTPService at 0.0.0.0:8090" I0829 05:18:42.222628 108 http_server.cc:320] "Started Metrics Service at 0.0.0.0:8002"
检查 NIM 运行状况#
Bash#
打开一个新的终端,保持当前终端运行已启动的服务。
在新的终端中,等待运行状况检查端点返回
{"status":"ready"}
后再继续。这可能需要几分钟时间。使用以下命令查询运行状况检查。curl -X 'GET' \ 'http://127.0.0.1:8000/v1/health/ready' \ -H 'accept: application/json'
Python#
import requests
r = requests.get("http://127.0.0.1:8000/v1/health/ready")
if r.status_code == 200:
print("NIM is healthy!")
else:
print("NIM is not ready!")
获取输入数据#
NIM 中使用的默认配置文件是球谐神经算子,它使用 73 个 ERA5 通道作为输入。此模型的具体输入/输出通道可以在其模型卡上找到。在本指南中,Earth-2 Studio 用于获取模型所需的输入数据。以下 Python 代码从 ARCO ERA5 获取 FourCastNet NIM 的初始状态,并将其保存到 NumPy 文件中
import numpy as np
from datetime import datetime
from earth2studio.data import ARCO
from earth2studio.models.px.sfno import VARIABLES
ds = ARCO()
da = ds(time=datetime(2023, 1, 1), variable=VARIABLES)
np.save("fcn_inputs.npy", da.to_numpy()[None].astype('float32'))
这将创建一个大小为 (1,1,73,721,1440) 的 NumPy 数组,这对应于模型卡中指定的所需输入字段。更广泛地说,这些维度映射到(批大小、提前期、变量、纬度和经度),如API 文档中所讨论的。
提示
有关此特定数据源的更多详细信息,请参阅 ARCO 数据源 API 文档。
推理请求#
使用 FourCastNet NIM 执行推理可以是标准的同步 post 请求。有关 NIM API 规范的完整文档,请访问 API 文档页面。
Bash#
curl -X POST \
-F "input_array=@fcn_inputs.npy" \
-F "input_time=2023-01-01T00:00:00Z" \
-F "simulation_length=4" \
-o output.tar \
http://127.0.0.1:8000/v1/infer
Python#
import requests
url = "http://127.0.0.1:8000/v1/infer"
files = {
"input_array": ("input_array", open("fcn_inputs.npy", "rb")),
}
data = {
"input_time": "2023-01-01T00:00:00Z",
"simulation_length": 4,
}
headers = {
"accept": "application/x-tar",
}
print("Sending post request to NIM")
r = requests.post(url, headers=headers, data=data, files=files, timeout=180)
if r.status_code != 200:
raise Exception(r.content)
else:
# Dump response to file
with open("output.tar", "wb") as tar:
tar.write(r.content)
结果#
结果位于 tar 文件中,可以使用以下命令进行浏览
tar -tvf output.tar
-rw-r--r-- 0/0 303166208 1970-01-01 00:00 000_000.npy
-rw-r--r-- 0/0 303166208 1970-01-01 00:00 006_000.npy
-rw-r--r-- 0/0 303166208 1970-01-01 00:00 012_000.npy
-rw-r--r-- 0/0 303166208 1970-01-01 00:00 018_000.npy
-rw-r--r-- 0/0 303166208 1970-01-01 00:00 024_000.npy
提示
tar 存档中填充了 NumPy 数组,这些数组的命名约定为 {lead time}_{batch index}.npy
。
警告
对于大多数推理调用,重要的是为对此 NIM 的请求指定更长的超时时间。
流式响应#
FourCastNet NIM 生成时间序列,并在生成每个时间步时将其流式传输回客户端。当创建在每个时间步上运行后续流程的管道时,这可能非常有用。以下代码片段可用于从 NIM 访问内存中生成的每个时间步。
import io
import tarfile
from pathlib import Path
import numpy as np
import requests
import tqdm
url = "http://127.0.0.1:8000/v1/infer"
files = {
"input_array": ("input_array", open("fcn_inputs.npy", "rb")),
}
data = {
"input_time": "2023-01-01T00:00:00Z",
"simulation_length": 4,
}
headers = {
"accept": "application/x-tar",
}
pbar = tqdm.tqdm(range(data["simulation_length"] + 1), desc="Forecast steps")
with (
requests.post(
url,
headers=headers,
files=files,
data=data,
timeout=300,
stream=True,
)
) as resp:
resp.raise_for_status()
with tarfile.open(fileobj=resp.raw, mode="r|") as tar_stream:
# Loop over file members from tar stream
for member in tar_stream:
arr_file = io.BytesIO()
arr_file.write(tar_stream.extractfile(member).read())
arr_file.seek(0)
data = np.load(arr_file)
# Array names are on the form <LEAD_TIME>_<BATCH_IDX>.npy
arr_lead_time, arr_batch_idx = (
int(x) for x in Path(member.name).stem.split("_", maxsplit=1)
)
pbar.write(f"Received data for lead {arr_lead_time} batch {arr_batch_idx}")
pbar.write(f"Output numpy {member.name} with shape {data.shape}")
pbar.update(1)
pbar.close()
结果后处理#
最后一步是可视化 NIM 生成的结果。虽然您可以使用许多不同的工具来创建不同的可视化效果,但本指南演示了如何使用 Matplotlib。
import tarfile
import io
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 2)
ax = ax.flatten()
with tarfile.open("output.tar") as tar:
for i, member in enumerate(tar.getmembers()):
arr_file = io.BytesIO()
arr_file.write(tar.extractfile(member).read())
arr_file.seek(0)
data = np.load(arr_file)
ax[i].set_title(f"Lead time: {6*i}hrs")
ax[i].imshow(data[0,0,0], vmin=-10, vmax=10, cmap="coolwarm")
if i == 3:
break
plt.savefig("output.png")
结果是 10 米高度处预测风速场的图。