PyNvVideoCodec 1.0

PyNvVideoCodec API 编程指南

概述

NVIDIA 的视频编解码器 SDK 通过高度优化的 C/C++ API 提供硬件加速的视频编码和解码。这种视频的编码和解码对于包括计算机视觉专家、研究人员和深度学习 (DL) 开发者在内的广泛用户也很有用。PyNvVideoCodec 的目标是为在 Python 中处理视频时利用此类视频编码和解码能力提供简单的 API。

PyNvVideoCodec 提供的编码和解码性能(FPS)接近视频编解码器 SDK。

PyNvVideoCodec 是一个库,它为硬件加速视频编码和解码的 C++ API 提供 Python 绑定。在内部,它利用 NVIDIA 视频编解码器 SDK 的核心 API,并提供 Python 固有的易用性。它依赖外部 FFmpeg 库进行媒体文件解复用。以下是显示客户端应用程序、PyNvVideoCodec 库和相关组件的高级框图。

图 1. 高级架构图

overview-arch.jpg

所有 API 都暴露在名为 PyNvVideoCodec 的 python 模块中。

本章的以下章节将介绍如何使用 PyNvVideoCodec API 加速视频解码和编码。

视频解复用

解复用 API

  • CreateDemuxer

    复制
    已复制!
                

    CreateDemuxer(filename: str) -> PyNvDemuxer parameters :param _filename: path to media file or encoded bitstream

    CreateDemuxer 函数接受扩展名为 .mp4.avi.mkv 的文件。

    CreateDemuxer 具有以下参数

    filename
    文件的绝对路径

解复用 API 用法

  1. 创建 Demuxer 实例,如下所示。唯一需要的参数是媒体文件名。
    复制
    已复制!
                

    import PyNvVideoCodec as nvc demuxer = nvc.CreateDemuxer(filename=media_file_name)

  2. demuxer 对象读取媒体文件并将其拆分为数据块 (PacketData)。

    以下示例显示如何从 demuxer 对象获取 PacketData

    复制
    已复制!
                

    import PyNvVideoCodec as nvc demuxer = nvc.CreateDemuxer(filename=media_file_name) for packet in demuxer: # process packet

PacketData

此类存储压缩数据。它通常由解复用器导出,然后作为解码器的输入传递。对于视频,它通常包含一个压缩帧。PacketData 类具有以下属性

bsl
存储基本码流数据的缓冲区大小(以字节为单位)。
bsl_data
指向包含基本码流数据的缓冲区的指针。
dts
数据包被解压缩的时间。
duration
此数据包在流时基中的持续时间。
key
值为 1 表示数据包数据属于关键帧。
pos
流中的字节位置。
pts
解压缩的数据包将呈现给用户的时间。

视频解码

解码 API

  1. CreateDecoder

    复制
    已复制!
                

    import PyNvVideoCodec as nvc decoder = nvc.CreateDecoder(gpuid=0,codec=nvc.cudaVideoCodec.H264,cudacontext=0,cudastream=0,usedevicememory=True, enableasyncallocations=False)

    以下是显示默认参数的 CreateDecoder API。在这种情况下,解码器在内部管理解码缓冲区的分配和释放。

    复制
    已复制!
                

    CreateDecoder( gpuid: int = 0, codec: PyNvVideoCodec. _PyNvVideoCodec.cudaVideoCodec = <cudaVideoCodec.H264: 4>, cudacontext: int = 0, cudastream: int = 0, usedevicememory: bool = 0) -> PyNvDecoder

    CreateDecoder 具有以下命名参数

    gpuid
    参数未使用,请忽略
    codec
    代码从 Demuxer 推断,可以从以下列表中取任何一个值
    • PyNvVideoCodec._PyNvVideoCodec.cudaVideoCodec.H264
    • PyNvVideoCodec._PyNvVideoCodec.cudaVideoCodec.HEVC
    • PyNvVideoCodec._PyNvVideoCodec.cudaVideoCodec.AV1
    cudacontext
    应用程序创建的 CUDA 上下文的句柄。
    cudastream
    应用程序创建的 CUDA 流的句柄
    usedevicememory
    值为 1 表示库内的表面分配位于设备内存中,值为 0 表示其位于主机内存中

    CreatedDecoder API 返回一个对象,该对象可用于将包含基本码流的数据包解码为原始视频帧。请参考 解复用 API 用法,将媒体文件拆分为 PacketData

  2. decoder.Decode() 接受 PacketData 作为输入。

    请参考 PacketData 了解更多详细信息

    复制
    已复制!
                

    import PyNvVideoCodec as nvc decoder = nvc.CreateDecoder( gpuid=0, codec=nvc.cudaVideoCodec.H264, cudacontext=0, cudastream=0, usedevicememory=True) for decodedframe in decoder.Decode(packet): # process decodedframe

视频解码详细信息

Python 示例 Decoder.py 展示了如何解码视频文件。

  1. 以下示例展示了如何创建解码器对象并提供原始压缩数据 (PacketData) 给 Decode()

    • 创建一个解码器对象,其中 CUDA 上下文在库内创建,默认 CUDA 流,输出表面在设备内存中。

      在这种情况下,解码器创建并管理自己的 CUDA 上下文和流。

      调用 Decode() 后的输出表面驻留在主机内存中

      以下示例演示了如何创建解码器对象并将解码帧作为设备内存缓冲区获取

      复制
      已复制!
                  

      import PyNvVideoCodec as nvc demuxer = nvc.CreateDemuxer( filename=enc_file_path) decoder = nvc.CreateDecoder(gpuid=0, codec=GetNvCodecId(), cudacontext=0, cudastream=0, usedevicememory=True) for packet in demuxer: for decoded_frame in decoder.Decode(packet): new_array = cast_address_to_1d_bytearray( base_address=luma_base_addr, size=decoded_frame.framesize()) #refer to Utils class for this implementation

    • 创建一个解码器对象,其中 CUDA 上下文在库内创建,默认 CUDA 流,输出表面在主机内存中。

      在这种情况下,解码器创建并管理自己的 CUDA 上下文和流。

      以下示例演示了如何创建解码器对象并将解码帧作为主机内存缓冲区获取

      复制
      已复制!
                  

      import PyNvVideoCodec as nvc import pycuda.driver as cuda demuxer = nvc.CreateDemuxer( filename=enc_file_path) decoder = nvc.CreateDecoder( gpuid=0, codec=GetNvCodecId(), cudacontext=0, cudastream=0, usedevicememory=False) seq_triggered = False for packet in demuxer: for decoded_frame in decoder.Decode(packet): if not seq_triggered: decoded_frame_size = nv_dec.GetFrameSize() raw_frame = np.ndarray( shape=decoded_frame_size, dtype=np.uint8) seq_triggered = True cuda.memcpy_dtoh( raw_frame, luma_base_addr)

    • 创建一个解码器对象,其中 CUDA 上下文、流和来自解码器的输出表面由外部管理器管理,位于设备内存中。

      在这种情况下,解码器使用外部创建的 CUDA 上下文和流。

      以下示例演示了如何创建解码器对象并从设备内存缓冲区获取解码帧。

      复制
      已复制!
                  

      import PyNvVideoCodec as nvc import pycuda.driver as cuda cuda.init() cuda_device = cuda.Device(0) cuda_ctx = cuda_device.retain_primary_context() cuda_ctx.push() cuda_stream_decoder = cuda.Stream() seq_triggered = False demuxer = nvc.CreateDemuxer( filename=enc_file_path) decoder = nvc.CreateDecoder( gpuid=0,codec=nvc.cudaVideoCodec.H264, cudacontext=cuda_ctx.handle, cudastream=cuda_stream_decoder.handle, usedevicememory=True) for packet in demuxer: for decoded_frame in decoder.Decode(packet): if not seq_triggered: decoded_frame_size = nv_dec.GetFrameSize() raw_frame = np.ndarray( shape=decoded_frame_size, dtype=np.uint8) seq_triggered = True cuda.memcpy_dtoh( raw_frame, luma_base_addr)

    • 创建一个启用异步分配的解码器对象。

      在这种情况下,解码器在外部提供的 CUDA 流和上下文上分配设备内存,而不是创建自己的内存。

      以下示例演示了如何创建解码器对象并将解码帧获取到在外部 CUDA 流上分配的设备内存缓冲区。

      复制
      已复制!
                  

      import PyNvVideoCodec as nvc import pycuda.driver as cuda cuda.init() cuda_device = cuda.Device(0) cuda_ctx = cuda_device.retain_primary_context() cuda_ctx.push() cuda_stream_decoder = cuda.Stream() cuda_stream_app = cuda.Stream() decoder = nvc.CreateDecoder( gpuid=0, codec=nvc.cudaVideoCodec.H264, cudacontext=cuda_ctx.handle, cudastream=cuda_stream_decoder.handle, usedevicememory=True, enableasyncallocations=True) raw_frame = None seq_triggered = False for packet in demuxer: for decoded_frame in decoder.Decode(packet): if not seq_triggered: decoded_frame_size = decoder.GetFrameSize() raw_frame = cuda.pagelocked_empty( shape=decoded_frame_size, dtype=np.uint8, order='C', mem_flags=0) # for stream aware allocations, we need to create page locked host # memory seq_triggered = True luma_base_addr = decoded_frame.GetPtrToPlane(0) decoder.WaitOnCUStream(cuda_stream_app.handle) cuda.memcpy_dtoh_async( raw_frame, luma_base_addr, cuda_stream_app) cuda_stream_app.synchronize()

      注意

      请注意在接收到解码帧后调用 WaitOnCUStream,因为分配是在与计划内存复制的流不同的流上完成的。应用程序需要等到分配完成才能计划内存复制。

  2. 客户端需要在使用互操作性 API 之前检查输出表面的 pitch,解码表面的 pitch 按 16 字节对齐。
  3. 要解码 SVC(可伸缩视频编码)流或具有动态分辨率更改的流,用户应启用在主机内存中转储输出
  4. 解码后,缓冲区的所有权仅保留在 PyNvVideoCodec 库中,客户端应用程序需要深度复制解码表面以供使用。
  5. NvCUVID 中的输出缓冲区大小为 DPB,对于 H264 编解码器,其大小为 16。

视频编码

编码 API

  1. CreateEncoder

    此方法返回编码器对象。

    以下示例展示了如何使用最少的参数创建编码器对象

    复制
    已复制!
                

    import PyNvVideoCodec as nvc encoder = nvc.CreateEncoder(1920,1080, "NV12", False)

    CreateEncoder 接受以下参数

    gpuid
    参数未使用,请忽略
    width
    编码视频的所需宽度
    height
    编码视频的所需高度
    format
    原始数据的表面格式,可以取以下任何值:“NV12”、“ARBG”、“ABGR”、“YUV444”、“YUV420”、“P010”和“YUV444_16bit”
    usecpuinputbuffer
    值为 0 表示编码的输入必须是设备内存,否则必须是主机内存。
    **kwargs
    允许细粒度控制的可选参数的键值对。请参考 可选参数 了解更多详细信息。

  2. Encode

    Encode 方法接受原始数据并返回编码码流数组

    Encode 的输入缓冲区可以是以下任何一种

    1. 字节的 1-D 数组,例如,我们可以从原始 YUV 中读取一块字节并将其作为参数传递,如下所示

      复制
      已复制!
                  

      import PyNvVideoCodec as nvc import numpy as np encoder = nvc.CreateEncoder( 1920, 1080, "NV12", True) frame_size = 1920 * 1080 * 1.5 chunk = np.fromfile( dec_file, np.uint8, count=frame_size) if chunk.size != 0: bitstream = nvenc.Encode(chunk) # encode frame one by one

    2. 实现 CUDA 数组接口的任何类的对象,如下所示

      重要的是要注意,对于多平面和半平面格式,如 YUV444 或 NV12,该类应为每个平面实现一个 CUDA 数组接口

      以下示例展示了如何将 NV12 表面格式表示为实现 CUDA 数组接口的类

      复制
      已复制!
                  

      import PyNvVideoCodec as nvc import numpy as np import pycuda.driver as cuda class AppFrame: def __init__(self, width, height, format): if format == "NV12": nv12_frame_size = int(width * height * 3 / 2) self.gpuAlloc = cuda.mem_alloc(nv12_frame_size) self.cai = [] self.cai.append(AppCAI( (height, width, 1), (width, 1, 1), "|u1", self.gpuAlloc)) chroma_alloc = int(self.gpuAlloc) + width * height self.cai.append(AppCAI((int(height / 2), int(width / 2), 2), (width, 2, 1), "|u1", chroma_alloc)) self.frameSize = nv12_frame_size def cuda(self): return self.cai encoder = nvc.CreateEncoder( 1920, 1080, "NV12", False) input_frame = AppFrame( 1920, 1080, "NV12") bitstream = encoder.Encode(input_gpu_frame)

      注意

      请注意,AppFrame 实现了 cuda 方法。只有当 AppFrame 对象实现了 cuda 方法时,Encode 才接受它。

    3. NCHW 张量,批次计数为 1 (N=1),通道计数为 1 (C=1)

      对于来自 1080p YUV 的单个帧,张量形状应为 [1,1,1620,1920]

      以下示例展示了如何将 NV12 表示为 NCHW 张量

      复制
      已复制!
                  

      import PyNvVideoCodec as nvc import numpy as np import torch encoder = nvc.CreateEncoder(1920,1080, "NV12", False) cuda0 = torch.device('cuda:0') input_tensor = torch.ones( [1620, 1920], dtype=torch.uint8, device=cuda0) bitstream = encoder.Encode(input_tensor)

      注意

      CreateEncoder 期间为 NV12 表面格式指定的宽度为 1080,但张量创建时的宽度为 1620。这种小的解决方法是必需的,因为编码硬件假定亮度平面和色度平面是连续的,而张量不适用于平面表面格式。

  3. EndEncode

    EndEncode 方法刷新编码器并从编码器队列返回待处理的码流数据

    以下示例展示了在编码 100 帧后,如何从 1080p 原始 YUV 的编码器队列中获取待处理的码流数据

    复制
    已复制!
                

    import PyNvVideoCodec as nvc import numpy as np encoder = nvc.CreateEncoder( 1920, 1080, "NV12", True) frame_size = 1920 * 1080 * 1.5 encoder = nvc.CreateEncoder( width, height, fmt, use_cpu_memory, **config_params) # create encoder object for i in range(100): chunk = np.fromfile( dec_file, np.uint8, count=frame_size) if chunk.size != 0: bitstream = encoder.Encode(chunk) # encode frame one by one bitstream = encoder.EndEncode() # flush encoder queue

    注意

    应该在最后调用 EndEncode(),因为它表示编码器输入数据的结束

  4. GetEncodeReconfigureParams Reconfigure

    Reconfigure API 允许客户端更改编码器初始化参数,而无需关闭现有的编码器会话并重新创建新的编码会话。这有助于客户端避免由于销毁和重新创建编码会话而引入的延迟。此 API 在视频会议、游戏流媒体等传输介质容易不稳定的场景中非常有用。

    但是,API 目前仅支持重新配置以下列出的参数

    • rateControlMode.
    • multiPass.
    • averageBitrate.
    • vbvBufferSize.
    • maxBitRate.
    • vbvInitialDelay.
    • frameRateNum.
    • frameRateDen.

    如果尝试重新配置不支持的参数,API 将失败。

    只有在创建编码器会话时设置了 NV_ENC_INITIALIZE_PARAMS::maxEncodeWidthNV_ENC_INITIALIZE_PARAMS::maxEncodeHeight,才有可能进行分辨率更改。

    如果客户端希望使用此 API 更改分辨率,建议通过将 NV_ENC_RECONFIGURE_PARAMS::forceIDR 设置为 1,强制将重新配置后的下一帧作为 IDR 帧。

    如果客户端希望重置内部速率控制状态,请将 NV_ENC_RECONFIGURE_PARAMS::resetEncoder to 设置为 1。

    以下示例展示了如何获取和更改可重新配置的参数

    复制
    已复制!
                

    import PyNvVideoCodec as nvc import numpy as np encoder = nvc.CreateEncoder(1920,1080, "NV12", True) t = encoder.GetEncodeReconfigureParams() t.averageBitrate = int(t.averageBitrate / 2) t.vbvBufferSize = int( t.averageBitrate * t.frameRateDen / t.frameRateNum) t.vbvInitialDelay = t.vbvBufferSize encoder.Reconfigure(t)

视频编码基础知识

PyNvVideoCodec 的设计旨在尽可能简化视频编码的使用,使用适当的默认值和简单的函数。但是,您也可以通过 C++ 接口访问详细的可选参数和 NVIDIA 视频技术堆栈提供的全部灵活性。

如果您熟悉视频编码基础知识,您可以直接跳转到可以与视频编码 API 一起使用的视频编码参数

NVIDIA GPU 允许编码 H.264、HEVC 和 AV1 内容。根据您的硬件代系,并非所有编解码器都可访问。请参阅 NVIDIA 硬件视频编码器 部分,了解每个 GPU 架构支持的编解码器。

表面格式支持

当前支持的输入格式为

  • NV12(8 位)
  • YUV 4:2:0(10 位)
  • YUV 4:4:4(8 位和 10 位)

10 位和 16 位输入帧都会导致 10 位编码。颜色空间转换矩阵可以由客户端在使用 CreateEncoder 期间使用 colorspace 选项指定。

调优

NVIDIA 编码器接口公开了四种不同的调优选项

  • 高质量适用于:- 高质量、容忍延迟的转码 - 视频存档 - OTT 流媒体编码
  • 低延迟适用于:- 云游戏 - 流媒体 - 视频会议 - 具有更大偶尔帧大小容忍度的高带宽通道
  • 超低延迟适用于:- 云游戏 - 流媒体 - 视频会议 - 在严格带宽受限的通道中
  • 无损适用于:- 保留原始视频素材以供以后编辑 - 常规无损数据存档(视频或非视频)

预设

对于每种调优信息,都有七个预设(从 P1(最高性能)到 P7(最低性能))可用于控制性能和质量的权衡。使用这些预设将自动设置所选调优信息的所有相关编码参数。这是 API 公开的粗略控制级别。

如果需要,可以调整预设中的特定属性和参数。这将在接下来的两个小节中进行解释。有关取决于所选预设的性能参考,请参阅 NVENC 编码性能(帧/秒 (fps))表。

速率控制和比特率

NVENC 提供了对其固件中实现的速率控制算法相关的各种参数的控制,使其能够根据您的质量、带宽和性能约束来调整比特率(或每秒编码视频内容所需的数据量)。NVENC 支持以下速率控制模式

  • 恒定比特率 (CBR)
  • 可变比特率 (VBR)
  • 恒定量化参数 (Constant QP)
  • 目标质量

比特率也可以限制为最大目标值。有关速率控制的更多信息,请参阅 NVENC 视频编码器 API 编程指南

构建优化的编码器

请参阅 推荐的 NVENC 设置部分,了解有关如何根据您的用例配置 NVENC 的更多信息。

视频编码参数详细信息

表 1. CreateEncoder 的可选参数
参数 类型 有效值 默认参数 描述
codec String h264, hevc, av1 h264  
bitrate Integer > 0 10000000U  
fps Integer > 0 30 要编码的视频的所需帧率(FPS),默认值设置为 30
initqp Integer > 0 未设置选项 初始量化参数 (QP)
idrperiod Integer > 0 250 Instantaneous Decoder Refresh (IDR) 帧之间的周期
constqp Integer 或 3 个整数的列表 >=0, <=51    
qmin Integer 或 3 个整数的列表 >=0, <=51 [30,30,30]  
gop Integer 或 3 个整数的列表 >0 根据其他设置而变化  
tuning_info String high_quality, low_latency, ultra_low_latency, lossless high_quality  
preset String P1P7 P4  
maxbitrate Integer >0 10000000U 用于可变比特率 (VBR) 编码的最大比特率,允许根据视频内容动态调整比特率
vbvinit Integer >0 10000000U  
vbvbufsize Integer >0 10000000U 目标客户端视频缓冲验证器 (VBV) 缓冲区大小,适用于 vbr
rc String cbr, constqp, vbr cbr 在恒定比特率 (CBR)、恒定 QP 或可变比特率 (VBR) 之间选择的速率控制 (RC) 类型
multipass String fullres, qres 默认禁用  
bf Integer >=0 根据 tuning_infopreset 而变化 指定 GOP 模式,如下所示:bf = 0: I, 1: IPP, 2: IBP, 3: IBBP
max_res 2 个整数的列表 >0 H264 为 4K,HEVC, AV1 为 8K 分辨率不大于硬件支持的最大分辨率,以便考虑动态分辨率更改。例如:[3840, 2160]
temporalaq Integer 0 或 1 0  
lookahead Integer >0 0 到 255 要前瞻的帧数。
aq Integer 0 或 1 0  
ldkfs Integer >=0, <255 0 低延迟关键帧缩放对于避免在 I 帧最终生成大量比特时出现通道拥塞非常有用
colorspace String bt601, bt709   为 ARGB/ABGR 输入指定此选项

timingInfo :: num_unit_in_ticks

Integer >0   指定时钟的时间单位数(如 ITU-T 规范附件 E 中定义)。仅限 HEVC 和 H264

timingInfo :: timescale

Integer >0   指定时钟的频率(如 ITU-T 规范附件 E 中定义)。仅限 HEVC 和 H264
slice::mode Integer 0 到 3 0 H.264 和 HEVC 编码的切片模式(AV1 不可用),可以是 0(基于 MB 的切片)、2(基于 MB 行的切片)或 3(切片数)
slice::data Integer 有效范围根据 slice::mode 而变化 0 指定 sliceMode 所需的参数。AV1 不支持 slice::data
repeatspspps Integer 0 或 1 0 为每个 IDR 帧启用写入 Sequence Parameter Set (SPS) 和 Picture Parameter Set (PPS)

与 DL/ML 框架的互操作性

以下示例展示了 DecodedFrame 如何被 PyTorch 消费,而无需显式内存复制

复制
已复制!
            

for packet in demuxer: for decoded_frame in decoder.Decode(packet): src_tensor = torch.from_dlpack(decoded_frame)

"PyNvVideoCodec API 可以与流行的 DL 框架(如 PyTorch 和 TensorRT)无缝(零拷贝)交换数据。PyNvVideoCodec 解码 API 解码的视频帧可以直接被 DL 框架消费。解码表面支持 DLpack 和 CUDA Array Interface 以实现此目的。类似地,编码 API 可以消费 DL 框架生成的视频帧。

以下示例展示了 NV12 1080p 表面的 DecodedFrame 类。DecodedFrame 实例包含 CAIMemoryView 列表。

对于 NV12,CAIMemoryView 列表将有 2 个条目,一个用于亮度分量,另一个用于色度分量。

复制
已复制!
            

import PyNvVideoCodec as nvc print(nvc.DecodedFrame) <DecodedFrame [timestamp=0, format=Pixel_Format.NV12, [<CAIMemoryView [1080, 1920, 1]>, <CAIMemoryView [540, 960, 2]>]]>

DecodedFrame 实现的方法如下:

  1. 访问 CAIMemoryView 的底层列表,其中每个视图都实现了 __cuda_array_interface__
    复制
    已复制!
                

    decodedFrame.cuda()

  2. 将半平面 NV12 和 YUV444 格式的 DecodedFrame 转换为 1-D 单通道张量。
    复制
    已复制!
                

    decodedFrame.nvcv_image()

  3. 访问 DLPack 方法。DLPack 是张量数据结构的中间内存表示标准,允许主要框架之间进行交换。
    • 张量的形状 - (描述轴长度的整数元组)
      复制
      已复制!
                  

      decodedFrame.shape()

    • 张量的步幅 - (描述内存中数据步幅的整数元组)
      复制
      已复制!
                  

      decodedFrame.shape()

    • 张量的 dtype - (数据类型)
      复制
      已复制!
                  

      decodedFrame.dtype()

  4. 访问指向底层 GPU 缓冲区的不透明指针。
    复制
    已复制!
                

    decodedFrame.__dlpack_device___

注意

为了为媒体文件创建自定义 DataLoader,请参考 NVVL

声明

本文档仅供参考,不得视为对产品的特定功能、条件或质量的保证。NVIDIA Corporation(“NVIDIA”)对本文档中包含的信息的准确性或完整性不作任何明示或暗示的陈述或保证,并且对本文档中包含的任何错误不承担任何责任。NVIDIA 对因使用此类信息或因使用此类信息而可能导致的侵犯第三方专利或其他权利的行为的后果或使用不承担任何责任。本文档不构成开发、发布或交付任何材料(如下定义)、代码或功能的承诺。

NVIDIA 保留随时更正、修改、增强、改进和对本文档进行任何其他更改的权利,恕不另行通知。

客户应在下订单前获取最新的相关信息,并应验证此类信息是否为最新且完整。

NVIDIA 产品的销售受 NVIDIA 在订单确认时提供的标准销售条款和条件的约束,除非 NVIDIA 和客户的授权代表签署的个人销售协议另有约定(“销售条款”)。NVIDIA 特此明确反对将任何客户通用条款和条件应用于购买本文档中引用的 NVIDIA 产品。本文档未直接或间接形成任何合同义务。

NVIDIA 产品并非设计、授权或保证适用于医疗、军事、飞机、航天或生命支持设备,也不适用于 NVIDIA 产品的故障或故障可能合理预期会导致人身伤害、死亡、财产或环境损害的应用。NVIDIA 对在此类设备或应用中包含和/或使用 NVIDIA 产品不承担任何责任,因此此类包含和/或使用由客户自行承担风险。

NVIDIA 不保证或声明基于本文档的产品将适用于任何特定用途。NVIDIA 不一定对每个产品的所有参数进行测试。客户全权负责评估和确定本文档中包含的任何信息的适用性,确保产品适用于客户计划的应用并适合该应用,并为该应用执行必要的测试,以避免应用或产品的默认设置。客户产品设计中的缺陷可能会影响 NVIDIA 产品的质量和可靠性,并可能导致超出本文档中包含的附加或不同条件和/或要求。NVIDIA 对可能基于或归因于以下原因的任何默认、损坏、成本或问题不承担任何责任:(i)以任何违反本文档的方式使用 NVIDIA 产品;或(ii)客户产品设计。

商标

NVIDIA、NVIDIA 徽标以及 cuBLAS、CUDA、CUDA Toolkit、cuDNN、DALI、DIGITS、DGX、DGX-1、DGX-2、DGX Station、DLProf、GPU、Jetson、Kepler、Maxwell、NCCL、Nsight Compute、Nsight Systems、NVCaffe、NVIDIA Deep Learning SDK、NVIDIA Developer Program、NVIDIA GPU Cloud、NVLink、NVSHMEM、PerfWorks、Pascal、SDK Manager、Tegra、TensorRT、TensorRT Inference Server、Tesla、TF-TRT、Triton Inference Server、Turing 和 Volta 是 NVIDIA Corporation 在美国和其他国家/地区的商标和/或注册商标。其他公司和产品名称可能是与其相关的各自公司的商标。

© 2010-2024 NVIDIA Corporation。保留所有权利。 上次更新时间:2024 年 4 月 15 日。