一文搞懂 GPU 共享方案: NVIDIA Time Slicing

简介: 本文主要分享 GPU 共享方案,包括如何安装、配置以及使用,最后通过分析源码了 TImeSlicing 的具体实现。通过配置 TImeSlicing 可以实现 Pod 共享一块物理 GPU,以提升资源利用率。

本文主要分享 GPU 共享方案,包括如何安装、配置以及使用,最后通过分析源码了 TImeSlicing 的具体实现。通过配置 TImeSlicing 可以实现 Pod 共享一块物理 GPU,以提升资源利用率。

<!--more-->

1.为什么需要 GPU 共享、切分等方案?

开始之前我们先思考一个问题,为什么需要 GPU 共享、切分等方案?

或者说是另外一个问题:明明直接在裸机环境使用,都可以多个进程共享 GPU,怎么到 k8s 环境就不行了

推荐阅读前面几篇文章:这两篇分享了如何在各个环境中使用 GPU,在 k8s 环境则推荐使用 NVIDIA 提供的 gpu-operator 快速部署环境。

这两篇则分析了 device-plugin 原理以及在 K8s 中创建一个申请 GPU 的 Pod 后的一些列动作,最终该 Pod 是如何使用到 GPU 的。

看完之后,大家应该就大致明白了。

资源感知

首先在 k8s 中资源是和节点绑定的,对于 GPU 资源,我们使用 NVIDIA 提供的 device-plugin 进行感知,并上报到 kube-apiserver,这样我们就能在 Node 对象上看到对应的资源了。

就像这样:

root@liqivm:~# k describe node gpu01|grep Capacity -A 7
Capacity:
  cpu:                128
  ephemeral-storage:  879000896Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             1056457696Ki
  nvidia.com/gpu:     8
  pods:               110

可以看到,该节点除了基础的 cpu、memory 之外,还有一个nvidia.com/gpu: 8 信息,表示该节点上有 8 个 GPU。

资源申请

然后我们就可以在创建 Pod 时申请对应的资源了,比如申请一个 GPU:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
  - name: gpu-container
    image: nvidia/cuda:11.0-base   # 一个支持 GPU 的镜像
    resources:
      limits:
        nvidia.com/gpu: 1          # 申请 1 个 GPU
    command: ["nvidia-smi"]         # 示例命令,显示 GPU 的信息
  restartPolicy: OnFailure

apply 该 yaml 之后,kube-scheduler 在调度该 Pod 时就会将其调度到一个拥有足够 GPU 资源的 Node 上。

同时该 Pod 申请的部分资源也会标记为已使用,不会在分配给其他 Pod。

到这里,问题的答案就已经很明显的。

  • 1)device-plugin 感知到节点上的物理 GPU 数量,上报到 kube-apiserver
  • 2)kube-scheduler 调度 Pod 时会根据 pod 中的 Request 消耗对应资源

即:Node 上的 GPU 资源被 Pod 申请之后,在 k8s 中就被标记为已消耗了,后续创建的 Pod 会因为资源不够导致无法调度

实际上:可能 GPU 性能比较好,可以支持多个 Pod 共同使用,但是因为 k8s 中的调度限制导致多个 Pod 无法正常共享。

因此,我们才需要 GPU 共享、切分等方案。

2. 什么是 Time Slicing 方案

NVIDIA 提供的 Time-Slicing GPUs in Kubernetes 是一种通过 oversubscription(超额订阅) 来实现 GPU 共享的策略,这种策略能让多个任务在同一个 GPU 上进行,而不是每个任务都独占一个 GPU。

虽然方案名称叫做 Time Slicing,但是和时间切片没有任何关系,实际上是一个 GPU 超卖方案。

比如节点上只有一个物理 GPU,正常安装 GPU Operator 之后,device plugin 检测到该节点上有 1 个 GPU,上报给 kubelet,然后 kubelet 更新到 kube-apiserver,我们就可以在 Node 对象上看到了:

root@liqivm:~# k describe node gpu01|grep Capacity -A 7
Capacity:
  cpu:                128
  ephemeral-storage:  879000896Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             1056457696Ki
  nvidia.com/gpu:     1
  pods:               110

此时,创建一个 Pod 申请 1 个 GPU 之后,第二个 Pod 就无法使用了,因为 GPU 资源不足无法调度。

但是 Time Slicing 可以进行 oversubscription 设置,将 device-plugin 上报的 GPU 数量进行扩大。

比如将其数量放大 10 倍,device plugin 就会上报该节点有 1*10 = 10 个 GPU,最终 kube-apiserver 则会记录该节点有 10 个 GPU:

root@liqivm:~# k describe node gpu01|grep Capacity -A 7
Capacity:
  cpu:                128
  ephemeral-storage:  879000896Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             1056457696Ki
  nvidia.com/gpu:     10
  pods:               110

这样,就可以供 10 个 Pod 使用了。

当然了,Time Slicing 方案也有缺点:多个 Pod 之间没有内存或者故障隔离,完全的共享,能使用多少内存和算力全靠多个 Pod 自行竞争。

ps:就和直接在宿主机上多个进程共享一个 GPU 基本一致

3. Time Slicing Demo

Time Slicing 由于是 NVIDIA 的方案,因此使用起来比较简单,只需要在部署完成 GPU Operator 之后进行配置即可。

首先参考这篇文章完成 GPU Operator 的部署

然后即可开始配置 TimeSlicing。

整体配置分为以下 3 个步骤:

  • 1)创建 TimeSlicing 配置
  • 根据官方文档描述,修改了 TimeSlicing 配置之后,device plugin Pod 不会自动重启,因此新的配置不会生效,需要手动重启对应 Pod。

  • 2)修改集群策略开启 Time Slicing,并指定让 device-plugin 使用第一步中创建的配置
  • 这里则是通过 Configmap 名称来指定
  • 3)(可选)给要使用 GPU TimeSlicing 的节点打上对应 label,实现不同 Node 使用不同策略
  • 比如不同节点上的 GPU 不同,那么可以根据 GPU 的算力或者内存情况设置不同的副本数以合理利用资源
  • 如果都是统一 GPU,则使用集群级别的统一配置即可
  • 配置开启 TimeSlicing
    创建 TimeSlicing 配置
    使用一个单独的 Configmap 来存放 TimeSlicing 的配置。
    这里使用集群级别的统一配置,配置文件 time-slicing-config-all.yaml 完整内容如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: time-slicing-config-all
data:
any: |-
  version: v1
  flags:
    migStrategy: none
  sharing:
    timeSlicing:
      renameByDefault: false
      failRequestsGreaterThanOne: false
      resources:
        - name: nvidia.com/gpu
          replicas: 4
具体配置含义参考官方文档
  • data.<key>: 配置的名字,可以为不同 Node 设置单独配置,后续通过名称引用对应配置。
  • 后续开启 TimeSlicing 时则根据 key 指定使用不同配置
  • 这里我们使用集群统一配置,因此创建一个 key 即可
  • flags.migStrategy:配置开启时间片之后如何处理 MIG 设备,默认为 none
  • renameByDefault:是否对 GPU 资源改名。
  • 设置为 true 之后,会使用<resource-name>.shared 替代原本的 <resource-name>。例如 nvidia.com/gpu 会变成 nvidia.com/gpu.shared ,显式告知使用者这是共享 GPU。
  • 默认为 false,即不改资源类型名,不过 Node 上的 label 也会改,比如使用时间片之前是nvidia.com/gpu.product=Tesla-T4, 使用后就会变成nvidia.com/gpu.product=Tesla-T4-SHARED 这样依旧可以通过 nodeSelector 来限制 Pod 调度节点,来控制是否使用共享的 GPU
  • 推荐使用 fasle 即可
  • failRequestsGreaterThanOne:开启后,当 Pod 请求 1 个以上的 shared GPU 时直接报错 UnexpectedAdmissionError。这个字段是通过报错的方式告诉使用者,请求多个 shared GPU 并不会增加 Pod 对该共享 GPU 的占用时间
  • resources.name:要通过时间分片提供访问的资源类似,比如nvidia.com/gpu
  • resources.replicas:可共享访问的资源数量,比如这里指定的 4 也就是 1 个该类型的 GPU 可以供 4 个 Pod 共享访问,也就是最终 Pod 上看到的 GPU 数量是物理 GPU 数量的 4 倍。
    将配置 Apply 到 gpu-operator 所在的 namespace
kubectl create -n gpu-operator -f time-slicing-config-all.yaml
  • 修改集群策略
    修改clusterpolicies.nvidia.com/cluster-policy 对象,让 device plugin 使用上一步创建的配置。
kubectl patch clusterpolicies.nvidia.com/cluster-policy \
  -n gpu-operator --type merge \
  -p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config-all", "default": "any"}}}}'
  • name:time-slicing-config-all 指定了配置文件对应的 Configmap 名称
  • default:any:表示默认配置为这个 Configmap 中的 key 为 any 的配置
    修改后 gpu-feature-discoverynvidia-device-plugin-daemonset pod 会重启,使用以下命令查看重启过程
kubectl get events -n gpu-operator --sort-by='.lastTimestamp'
  • 验证 TimeSlicing 是否生效
    查看 Node 上的 GPU 信息
    首先查看一下 Node 信息,确认 TimeSlicing 生效了
kubectl describe node xxx
  • 正常结果如下
...
Labels:
                nvidia.com/gpu.count=4
                nvidia.com/gpu.product=Tesla-T4-SHARED
                nvidia.com/gpu.replicas=4
Capacity:
nvidia.com/gpu: 16
...
Allocatable:
nvidia.com/gpu: 16
...
  • 增加了几个 label,
  • nvidia.com/gpu.product=Tesla-T4-SHARED
  • nvidia.com/gpu.replicas=4
    根据nvidia.com/gpu.count=4 可知,节点上有 4 张 GPU,然后由于使用了时间片,且配置的nvidia.com/gpu.replicas=4 副本数为 4,因此最终节点上 device plugin 上报的 GPU 数量就是 4*4 = 16 个。
    验证 GPU 能否正常使用
    创建一个 Deployment 来验证,GPU 能否正常使用。
    这里副本数指定为 5,因为集群里只有 4 张 GPU,如果 TimeSlicing 未生效,那么有一个 Pod 肯定会应为拿不到 GPU 资源而 pending。
apiVersion: apps/v1
kind: Deployment
metadata:
name: time-slicing-verification
labels:
  app: time-slicing-verification
spec:
replicas: 2
selector:
  matchLabels:
    app: time-slicing-verification
template:
  metadata:
    labels:
      app: time-slicing-verification
  spec:
    tolerations:
      - key: nvidia.com/gpu
        operator: Exists
        effect: NoSchedule
    hostPID: true
    containers:
      - name: cuda-sample-vector-add
        image: "https://www.pxwang.com/nvidia/k8s/cuda-sample:vectoradd-cuda11.7.1-ubuntu20.04"
        command: ["/bin/bash", "-c", "--"]
        args:
          - while true; do /cuda-samples/vectorAdd; done
        resources:
         limits:
           nvidia.com/gpu: 1
  • 会启动 5 个 Pod,
    查看情况
$ kubectl get pods
NAME                                         READY   STATUS    RESTARTS   AGE
time-slicing-verification-7cdc7f87c5-lkd9d   1/1     Running   0          23s
time-slicing-verification-7cdc7f87c5-rrzq7   1/1     Running   0          23s
time-slicing-verification-7cdc7f87c5-s8qwk   1/1     Running   0          23s
time-slicing-verification-7cdc7f87c5-xhmb7   1/1     Running   0          23s
time-slicing-verification-7cdc7f87c5-zsncp   1/1     Running   0          23s
  • 个 Pod 都启动了,说明时间片时成功的。
    随便查看一个 Pod 的日志
$ kubectl logs deploy/time-slicing-verification
Found 5 pods, using pod/time-slicing-verification-7cdc7f87c5-s8qwk
[Vector addition of 50000 elements]
Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Copy output data from the CUDA device to the host memory
Test PASSED
Done
[Vector addition of 50000 elements]
Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Copy output data from the CUDA device to the host memory
...
  • 有 Test PASSED 则说明成功了。
    说明 TimeSlicing 配置生效了。
    4. 使用 Node 级别的单独配置
    前面只创建了一个名称为 any 的配置,并在 clusterpolicy 中指明了使用该配置为默认配置,因此集群中的全部节点都会使用该配置来做时间片。
    但是可能集群中不同节点上的 GPU 型号不同,因此需要共享分副本数可以调整,性能好的副本数就调大一点,性能差的就小一点。
    本章主要记录怎么为不同的节点使用不同的配置。
实际上是为不同的 GPU 准备不同的配置。
  • 创建时间片配置
    同样的创建 TimeSlicing 配置,不过这次 Configmap 中写了两个配置,而且是以 GPU 型号命名的
apiVersion: v1
kind: ConfigMap
metadata:
name: time-slicing-config-fine
data:
a100-40gb: |-
  version: v1
  flags:
    migStrategy: mixed
  sharing:
    timeSlicing:
      resources:
      - name: nvidia.com/gpu
        replicas: 8
      - name: nvidia.com/mig-1g.5gb
        replicas: 2
      - name: nvidia.com/mig-2g.10gb
        replicas: 2
      - name: nvidia.com/mig-3g.20gb
        replicas: 3
      - name: nvidia.com/mig-7g.40gb
        replicas: 7
tesla-t4: |-
  version: v1
  flags:
    migStrategy: none
  sharing:
    timeSlicing:
      resources:
      - name: nvidia.com/gpu
        replicas: 4
  • 可以看到,分别对 A100 和 Tesla T4 这两种 GPU 做了配置。
  • a100-40gb:A100 支持 MIG,因此增加了 MIG 部分的配置,若没有则指定为 none 即可
  • 然后根据 MIG 实例分别指定不同的 replicas 数
  • tesla-t4:Tesla T4 GPU 性能比较差,因此 replicas 指定为 4 即可
    将配置 Apply 到 gpu-operator 所在的 namespace
kubectl create -n gpu-operator -f time-slicing-config-all.yaml
  • 修改集群策略
    同样的,修改一下 cluster-policy 指定 device plugin 使用的 Configmap,这次与之前的区别在于,这里没有指定 default 配置
kubectl patch clusterpolicies.nvidia.com/cluster-policy \
  -n gpu-operator --type merge \
  -p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config-fine"}}}}'
  • 没有指定 default 时,device-plugin 则会根据 node 上的 label (nvidia.com/device-plugin.config)来获取要使用的配置。
    为节点打 label
    在节点上打上下面的 label,这样该节点上的 device plugin 就会根据该 label 的 value 来使用对应名字的配置了。
    比如这里,就是有这个 label 的节点就使用名叫 tesla-t4 的配置。
kubectl label node <node-name> nvidia.com/device-plugin.config=tesla-t4
  • 一般都是以 GPU 型号命名,然后给使用该 GPU 的节点都打上对应 label,这样便于查看。
    5. 关闭 TimeSlicing
    想关闭 TimeSlicing 配置也很简单,直接更新 集群策略 把 device plugin 下的 config 这一段去掉即可。
devicePlugin:
  config:
    default: any
    name: time-slicing-config-all
  enabled: true
  env:
  - name: PASS_DEVICE_SPECS
    value: "true"
  - name: FAIL_ON_INIT_ERROR
    value: "true"
  • 命令如下:
kubectl patch clusterpolicies.nvidia.com/cluster-policy -n gpu-operator --type json -p '[{"op": "remove", "path": "/spec/devicePlugin/config"}]'
  • 然后重启一下 device-plugin pod
kubectl rollout restart -n gpu-operator daemonset/nvidia-device-plugin-daemonset
  • 不出意外的话就关掉了,再次查看 Pod 信息,GPU 就变成了物理 GPU 数量,说明关闭成功。
kubectl get node xxx -oyaml
addresses:
- address: 172.18.187.224
  type: InternalIP
- address: izj6c5dnq07p1ic04ei9vwz
  type: Hostname
allocatable:
  cpu: "4"
  ephemeral-storage: "189889991571"
  hugepages-1Gi: "0"
  hugepages-2Mi: "0"
  memory: 15246720Ki
  nvidia.com/gpu: "1"
  pods: "110"
  • 6.源码分析
    简单看下源码,分析 TimeSlicing 是怎么实现的。
    首先是 device-plugin 可以接收的配置
// api/config/v1/config.go#L32
// Config is a versioned struct used to hold configuration information.
type Config struct {
  Version   string    `json:"version"             yaml:"version"`
  Flags     Flags     `json:"flags,omitempty"     yaml:"flags,omitempty"`
  Resources Resources `json:"resources,omitempty" yaml:"resources,omitempty"`
  Sharing   Sharing   `json:"sharing,omitempty"   yaml:"sharing,omitempty"`
}
  • 这也就是我们在 clusterPolicy 中配置的:
apiVersion: v1
kind: ConfigMap
metadata:
name: time-slicing-config-all
data:
any: |-
  version: v1
  flags:
    migStrategy: none
  sharing:
    timeSlicing:
      renameByDefault: false
      failRequestsGreaterThanOne: false
      resources:
        - name: nvidia.com/gpu
          replicas: 4
  • 这里我们关注 resources 中的 replicas 参数,正是这个参数定义了 oversubscription(超额订阅) 的额度。
resources:
        - name: nvidia.com/gpu
          replicas: 4
  • 看下代码中是什么生效的
// internal/rm/device_map.go#L282

// updateDeviceMapWithReplicas returns an updated map of resource names to devices with replica

// information from the active replicated resources config.

func updateDeviceMapWithReplicas(replicatedResources *spec.ReplicatedResources, oDevices DeviceMap) (DeviceMap, error) {

devices := make(DeviceMap)
// Begin by walking replicatedResources.Resources and building a map of just the resource names.
names := make(map[spec.ResourceName]bool)
for _, r := range replicatedResources.Resources {
    names[r.Name] = true
}
// Copy over all devices from oDevices without a resource reference in TimeSlicing.Resources.
for r, ds := range oDevices {
    if !names[r] {
        devices[r] = ds
    }
}
// Walk shared Resources and update devices in the device map as appropriate.
for _, resource := range replicatedResources.Resources {
    r := resource
    // Get the IDs of the devices we want to replicate from oDevices
    ids, err := oDevices.getIDsOfDevicesToReplicate(&r)
    if err != nil {
        return nil, fmt.Errorf("unable to get IDs of devices to replicate for '%v' resource: %v", r.Name, err)
    }
    // Skip any resources not matched in oDevices
    if len(ids) == 0 {
        continue
    }
    // Add any devices we don't want replicated directly into the device map.
    for _, d := range oDevices[r.Name].Difference(oDevices[r.Name].Subset(ids)) {
        devices.insert(r.Name, d)
    }
    // Create replicated devices add them to the device map.
    // Rename the resource for replicated devices as requested.
    name := r.Name
    if r.Rename != "" {
        name = r.Rename
    }
    for _, id := range ids {
        for i := 0; i < r.Replicas; i++ {
            annotatedID := string(NewAnnotatedID(id, i))
            replicatedDevice := *(oDevices[r.Name][id])
            replicatedDevice.ID = annotatedID
            replicatedDevice.Replicas = r.Replicas
            devices.insert(name, &replicatedDevice)
        }
    }
}
return devices, nil

}

核心部分如下:

for _, id := range ids {

for i := 0; i < r.Replicas; i++ {

annotatedID := string(NewAnnotatedID(id, i))
replicatedDevice := *(oDevices[r.Name][id])
replicatedDevice.ID = annotatedID
replicatedDevice.Replicas = r.Replicas
devices.insert(name, &replicatedDevice)

}

}

可以看到,这里是双层 for 循环,对 device 数量进行了一个复制的操作,这样每张 GPU 都可以被使用 Replicas 次了。
其他属性都没变,只是把 deviceID 进行了处理,便于区分

// NewAnnotatedID creates a new AnnotatedID from an ID and a replica number.

func NewAnnotatedID(id string, replica int) AnnotatedID {

return AnnotatedID(fmt.Sprintf("%s::%d", id, replica))

}

然后在真正挂载时则进行 split 拿到 id 和 replicas 信息

// Split splits a AnnotatedID into its ID and replica number parts.

func (r AnnotatedID) Split() (string, int) {

split := strings.SplitN(string(r), "::", 2)
if len(split) != 2 {
    return string(r), 0
}
replica, _ := strconv.ParseInt(split[1], 10, 0)
return split[0], int(replica)


至此,我们就分析完了 TImeSlicing 的具体实现,其实很简单,就是根据配置的 replicas 参数对 device plugin 感知到的设备进行复制,并在 DeviceID 使用特定格式进行标记便于区分。

## 7. 小结

本文主要分享了 NVIDIA Time Slicing 这个 GPU 共享方案,包括即实现原理,以及配置和使用方式。

最后通过分析源码的方式探索了 TImeSlicing 的代码实现。

**为什么需要 GPU 共享、切分?**

在 k8s 中使用默认 device plugin 时,GPU 资源和物理 GPU 是一一对应的,导致一个物理 GPU 被一个 Pod 申请后,其他 Pod 就无法使用了。

为了提高资源利用率,因此我们需要 GPU 共享、切分等方案。

**什么是 TimeSlicing?**

TimeSlicing 是一种通过 oversubscription(超额订阅) 来实现 GPU 共享的策略,这种策略能让多个任务在同一个 GPU 上进行,而不是每个任务都独占一个 GPU。

**如何开启 TimeSlicing**

* 1)创建 TimeSlicing 配置

 * 可以是集群统一配置,也可以是 Node 级别的配置,主要根据不同节点上的 GPU 进行配置

 * 如果集群中所有节点 GPU 型号都一致,则使用集群统一配置即可,若不一致则根据 节点上的 GPU 性能修改配置

 2)修改 cluster-policy,增加 TimeSlicing 相关配置

作为这两个步骤之后,TimeSlicing 就开启了,再次查看 Node 信息时会发现 GPU 数量变多了。

**TImeSlicing 实现原理**

根据配置的 replicas 参数对 device plugin 感知到的设备进行复制,并在 DeviceID 使用特定格式进行标记便于区分。

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
目录
相关文章
|
人工智能 缓存 调度
技术改变AI发展:RDMA能优化吗?GDR性能提升方案(GPU底层技术系列二)
随着人工智能(AI)的迅速发展,越来越多的应用需要巨大的GPU计算资源。GPUDirect RDMA 是 Kepler 级 GPU 和 CUDA 5.0 中引入的一项技术,可以让使用pcie标准的gpu和第三方设备进行直接的数据交换,而不涉及CPU。
137372 6
|
机器学习/深度学习 虚拟化 数据中心
NVIDIA T4和A10:不同应用场景下的GPU加速器选择
在数据中心和云计算领域,GPU加速器扮演着至关重要的角色。NVIDIA T4和A10是两款适用于不同应用场景的GPU加速器。本文将比较它们的性能和适用场景,帮助读者更好地选择适合自己需求的GPU实例。
6036 0
|
3月前
|
并行计算 PyTorch 算法框架/工具
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
本文探讨了如何通过技术手段混合使用AMD与NVIDIA GPU集群以支持PyTorch分布式训练。面对CUDA与ROCm框架互操作性不足的问题,文章提出利用UCC和UCX等统一通信框架实现高效数据传输,并在异构Kubernetes集群中部署任务。通过解决轻度与强度异构环境下的挑战,如计算能力不平衡、内存容量差异及通信性能优化,文章展示了如何无需重构代码即可充分利用异构硬件资源。尽管存在RDMA验证不足、通信性能次优等局限性,但该方案为最大化GPU资源利用率、降低供应商锁定提供了可行路径。源代码已公开,供读者参考实践。
231 3
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
|
6月前
|
存储 算法 数据挖掘
重磅发布 | OpenSearch推出向量检索GPU图算法方案并支持GPU规格售卖
OpenSearch向量检索版推出了面向企业开发者的GPU图算法方案(CAGRA算法),支持客户直接购买GPU规格节点,是国内首家支持GPU规格的向量检索产品。
533 12
|
机器学习/深度学习 人工智能 弹性计算
阿里云GPU云服务器有哪些方案
阿里云GPU云服务器有哪些方案
|
并行计算 固态存储 Ubuntu
基因组大数据计算: CPU和GPU加速方案深度评测
基因组大数据计算: CPU和GPU加速方案深度评测
449 0
基因组大数据计算: CPU和GPU加速方案深度评测
|
12月前
|
机器学习/深度学习 人工智能 弹性计算
阿里云GPU服务器全解析_GPU服务器租用费用_NVIDIA A10、V100、T4、P4、P100 GPU卡
阿里云GPU云服务器提供NVIDIA A10、V100、T4、P4、P100等多种GPU卡,结合高性能CPU,单实例计算性能高达5PFLOPS。支持2400万PPS及160Gbps内网带宽。实例规格多样,如A10卡GN7i(3213.99元/月)、V100-16G卡GN6v(3830.00元/月)等。适用于深度学习、科学计算、图形处理等场景。GPU软件如AIACC-Training、AIACC-Inference助力性能优化。购买方式灵活,客户案例包括深势科技、流利说、小牛翻译。
1969 0
|
机器学习/深度学习 人工智能 弹性计算
阿里云林立翔:基于阿里云GPU的AIGC小规模训练优化方案
阿里云弹性计算林立翔在【AIGC】话题下带来了题为《基于阿里云GPU的AIGC小规模训练优化方案》的主题演讲,围绕生成式AI技术栈、生成式AI微调训练和性能分析、ECS GPU实例为生成式AI提供算力保障、应用场景案例等相关话题展开。
|
12月前
|
XML 机器学习/深度学习 监控
性能监控之Telegraf+InfluxDB+Grafana NVIDIA GPU实时监控
【6月更文挑战12天】性能监控之Telegraf+InfluxDB+Grafana NVIDIA GPU实时监控
311 0
|
人工智能 弹性计算 安全
【Hello AI】GPU容器共享技术cGPU
GPU容器共享技术cGPU是阿里云基于内核虚拟GPU隔离的容器共享技术。即多个容器共享一张GPU卡,从而实现业务的安全隔离,提高GPU硬件资源的利用率并降低使用成本。
【Hello AI】GPU容器共享技术cGPU

热门文章

最新文章

下一篇
oss创建bucket