日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2025/5/22 编程问答 79 如意码农
生活随笔 收集整理的這篇文章主要介紹了 一文搞懂 GPU 共享方案: NVIDIA Time Slicing 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文主要分享 GPU 共享方案,包括如何安裝、配置以及使用,最后通過分析源碼了 TImeSlicing 的具體實(shí)現(xiàn)。通過配置 TImeSlicing 可以實(shí)現(xiàn) Pod 共享一塊物理 GPU,以提升資源利用率。

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

開始之前我們先思考一個(gè)問題,為什么需要 GPU 共享、切分等方案?

或者說是另外一個(gè)問題:明明直接在裸機(jī)環(huán)境使用,都可以多個(gè)進(jìn)程共享 GPU,怎么到 k8s 環(huán)境就不行了。

推薦閱讀前面幾篇文章:這兩篇分享了如何在各個(gè)環(huán)境中使用 GPU,在 k8s 環(huán)境則推薦使用 NVIDIA 提供的 gpu-operator 快速部署環(huán)境。

GPU 環(huán)境搭建指南:如何在裸機(jī)、Docker、K8s 等環(huán)境中使用 GPU

GPU 環(huán)境搭建指南:使用 GPU Operator 加速 Kubernetes GPU 環(huán)境搭建

這兩篇?jiǎng)t分析了 device-plugin 原理以及在 K8s 中創(chuàng)建一個(gè)申請 GPU 的 Pod 后的一些列動(dòng)作,最終該 Pod 是如何使用到 GPU 的。

Kubernetes教程(二一)---自定義資源支持:K8s Device Plugin 從原理到實(shí)現(xiàn)

Kubernetes教程(二二)---在 K8S 中創(chuàng)建 Pod 是如何使用到 GPU 的:device plugin&nvidia-container-toolkit 源碼分析

看完之后,大家應(yīng)該就大致明白了。

資源感知

首先在 k8s 中資源是和節(jié)點(diǎn)綁定的,對于 GPU 資源,我們使用 NVIDIA 提供的 device-plugin 進(jìn)行感知,并上報(bào)到 kube-apiserver,這樣我們就能在 Node 對象上看到對應(yīng)的資源了。

就像這樣:

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

可以看到,該節(jié)點(diǎn)除了基礎(chǔ)的 cpu、memory 之外,還有一個(gè)nvidia.com/gpu: 8 信息,表示該節(jié)點(diǎn)上有 8 個(gè) GPU。

資源申請

然后我們就可以在創(chuàng)建 Pod 時(shí)申請對應(yīng)的資源了,比如申請一個(gè) GPU:

apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
containers:
- name: gpu-container
image: nvidia/cuda:11.0-base # 一個(gè)支持 GPU 的鏡像
resources:
limits:
nvidia.com/gpu: 1 # 申請 1 個(gè) GPU
command: ["nvidia-smi"] # 示例命令,顯示 GPU 的信息
restartPolicy: OnFailure

apply 該 yaml 之后,kube-scheduler 在調(diào)度該 Pod 時(shí)就會(huì)將其調(diào)度到一個(gè)擁有足夠 GPU 資源的 Node 上。

同時(shí)該 Pod 申請的部分資源也會(huì)標(biāo)記為已使用,不會(huì)在分配給其他 Pod。

到這里,問題的答案就已經(jīng)很明顯的。

  • 1)device-plugin 感知到節(jié)點(diǎn)上的物理 GPU 數(shù)量,上報(bào)到 kube-apiserver
  • 2)kube-scheduler 調(diào)度 Pod 時(shí)會(huì)根據(jù) pod 中的 Request 消耗對應(yīng)資源

即:Node 上的 GPU 資源被 Pod 申請之后,在 k8s 中就被標(biāo)記為已消耗了,后續(xù)創(chuàng)建的 Pod 會(huì)因?yàn)橘Y源不夠?qū)е聼o法調(diào)度

實(shí)際上:可能 GPU 性能比較好,可以支持多個(gè) Pod 共同使用,但是因?yàn)?k8s 中的調(diào)度限制導(dǎo)致多個(gè) Pod 無法正常共享。

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

2. 什么是 Time Slicing 方案

NVIDIA 提供的 Time-Slicing GPUs in Kubernetes 是一種通過 oversubscription(超額訂閱) 來實(shí)現(xiàn) GPU 共享的策略,這種策略能讓多個(gè)任務(wù)在同一個(gè) GPU 上進(jìn)行,而不是每個(gè)任務(wù)都獨(dú)占一個(gè) GPU。

雖然方案名稱叫做 Time Slicing,但是和時(shí)間切片沒有任何關(guān)系,實(shí)際上是一個(gè) GPU 超賣方案。

比如節(jié)點(diǎn)上只有一個(gè)物理 GPU,正常安裝 GPU Operator 之后,device plugin 檢測到該節(jié)點(diǎn)上有 1 個(gè) GPU,上報(bào)給 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

此時(shí),創(chuàng)建一個(gè) Pod 申請 1 個(gè) GPU 之后,第二個(gè) Pod 就無法使用了,因?yàn)?GPU 資源不足無法調(diào)度。

但是 Time Slicing 可以進(jìn)行 oversubscription 設(shè)置,將 device-plugin 上報(bào)的 GPU 數(shù)量進(jìn)行擴(kuò)大。

比如將其數(shù)量放大 10 倍,device plugin 就會(huì)上報(bào)該節(jié)點(diǎn)有 1*10 = 10 個(gè) GPU,最終 kube-apiserver 則會(huì)記錄該節(jié)點(diǎn)有 10 個(gè) 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 個(gè) Pod 使用了。

當(dāng)然了,Time Slicing 方案也有缺點(diǎn):多個(gè) Pod 之間沒有內(nèi)存或者故障隔離,完全的共享,能使用多少內(nèi)存和算力全靠多個(gè) Pod 自行競爭。

ps:就和直接在宿主機(jī)上多個(gè)進(jìn)程共享一個(gè) GPU 基本一致

3. Time Slicing Demo

Time Slicing 由于是 NVIDIA 的方案,因此使用起來比較簡單,只需要在部署完成 GPU Operator 之后進(jìn)行配置即可。

首先參考這篇文章完成 GPU Operator 的部署 --> GPU 環(huán)境搭建指南:使用 GPU Operator 加速 Kubernetes GPU 環(huán)境搭建

然后即可開始配置 TimeSlicing。

整體配置分為以下 3 個(gè)步驟:

  • 1)創(chuàng)建 TimeSlicing 配置

    • 根據(jù)官方文檔描述,修改了 TimeSlicing 配置之后,device plugin Pod 不會(huì)自動(dòng)重啟,因此新的配置不會(huì)生效,需要手動(dòng)重啟對應(yīng) Pod。

    • kubectl rollout restart -n gpu-operator daemonset/nvidia-device-plugin-daemonset
  • 2)修改集群策略開啟 Time Slicing,并指定讓 device-plugin 使用第一步中創(chuàng)建的配置

    • 這里則是通過 Configmap 名稱來指定
  • 3)(可選)給要使用 GPU TimeSlicing 的節(jié)點(diǎn)打上對應(yīng) label,實(shí)現(xiàn)不同 Node 使用不同策略

    • 比如不同節(jié)點(diǎn)上的 GPU 不同,那么可以根據(jù) GPU 的算力或者內(nèi)存情況設(shè)置不同的副本數(shù)以合理利用資源
    • 如果都是統(tǒng)一 GPU,則使用集群級(jí)別的統(tǒng)一配置即可

配置開啟 TimeSlicing

創(chuàng)建 TimeSlicing 配置

使用一個(gè)單獨(dú)的 Configmap 來存放 TimeSlicing 的配置。

這里使用集群級(jí)別的統(tǒng)一配置,配置文件 time-slicing-config-all.yaml 完整內(nèi)容如下:

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

具體配置含義參考官方文檔:about-configuring-gpu-time-slicing

  • data.<key>: 配置的名字,可以為不同 Node 設(shè)置單獨(dú)配置,后續(xù)通過名稱引用對應(yīng)配置。

    • 后續(xù)開啟 TimeSlicing 時(shí)則根據(jù) key 指定使用不同配置
    • 這里我們使用集群統(tǒng)一配置,因此創(chuàng)建一個(gè) key 即可
  • flags.migStrategy:配置開啟時(shí)間片之后如何處理 MIG 設(shè)備,默認(rèn)為 none
  • renameByDefault:是否對 GPU 資源改名。
    • 設(shè)置為 true 之后,會(huì)使用<resource-name>.shared 替代原本的 <resource-name>。例如 nvidia.com/gpu 會(huì)變成 nvidia.com/gpu.shared ,顯式告知使用者這是共享 GPU。
    • 默認(rèn)為 false,即不改資源類型名,不過 Node 上的 label 也會(huì)改,比如使用時(shí)間片之前是nvidia.com/gpu.product=Tesla-T4, 使用后就會(huì)變成nvidia.com/gpu.product=Tesla-T4-SHARED 這樣依舊可以通過 nodeSelector 來限制 Pod 調(diào)度節(jié)點(diǎn),來控制是否使用共享的 GPU
    • 推薦使用 fasle 即可
  • failRequestsGreaterThanOne:開啟后,當(dāng) Pod 請求 1 個(gè)以上的 shared GPU 時(shí)直接報(bào)錯(cuò) UnexpectedAdmissionError。這個(gè)字段是通過報(bào)錯(cuò)的方式告訴使用者,請求多個(gè) shared GPU 并不會(huì)增加 Pod 對該共享 GPU 的占用時(shí)間。
  • resources.name:要通過時(shí)間分片提供訪問的資源類似,比如nvidia.com/gpu
  • resources.replicas:可共享訪問的資源數(shù)量,比如這里指定的 4 也就是 1 個(gè)該類型的 GPU 可以供 4 個(gè) Pod 共享訪問,也就是最終 Pod 上看到的 GPU 數(shù)量是物理 GPU 數(shù)量的 4 倍。

將配置 Apply 到 gpu-operator 所在的 namespace

kubectl create -n gpu-operator -f time-slicing-config-all.yaml

修改集群策略

修改clusterpolicies.nvidia.com/cluster-policy 對象,讓 device plugin 使用上一步創(chuàng)建的配置。

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 指定了配置文件對應(yīng)的 Configmap 名稱
  • default:any:表示默認(rèn)配置為這個(gè) Configmap 中的 key 為 any 的配置

修改后 gpu-feature-discoverynvidia-device-plugin-daemonset pod 會(huì)重啟,使用以下命令查看重啟過程

kubectl get events -n gpu-operator --sort-by='.lastTimestamp'

驗(yàn)證 TimeSlicing 是否生效

查看 Node 上的 GPU 信息

首先查看一下 Node 信息,確認(rèn) TimeSlicing 生效了

kubectl describe node xxx

正常結(jié)果如下

...
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
...

增加了幾個(gè) label,

  • nvidia.com/gpu.product=Tesla-T4-SHARED
  • nvidia.com/gpu.replicas=4

根據(jù)nvidia.com/gpu.count=4 可知,節(jié)點(diǎn)上有 4 張 GPU,然后由于使用了時(shí)間片,且配置的nvidia.com/gpu.replicas=4 副本數(shù)為 4,因此最終節(jié)點(diǎn)上 device plugin 上報(bào)的 GPU 數(shù)量就是 4*4 = 16 個(gè)。

驗(yàn)證 GPU 能否正常使用

創(chuàng)建一個(gè) Deployment 來驗(yàn)證,GPU 能否正常使用。

這里副本數(shù)指定為 5,因?yàn)榧豪镏挥?4 張 GPU,如果 TimeSlicing 未生效,那么有一個(gè) Pod 肯定會(huì)應(yīng)為拿不到 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: "nvcr.io/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

會(huì)啟動(dòng) 5 個(gè) 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

5 個(gè) Pod 都啟動(dòng)了,說明時(shí)間片時(shí)成功的。

隨便查看一個(gè) 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 級(jí)別的單獨(dú)配置

前面只創(chuàng)建了一個(gè)名稱為 any 的配置,并在 clusterpolicy 中指明了使用該配置為默認(rèn)配置,因此集群中的全部節(jié)點(diǎn)都會(huì)使用該配置來做時(shí)間片。

但是可能集群中不同節(jié)點(diǎn)上的 GPU 型號(hào)不同,因此需要共享分副本數(shù)可以調(diào)整,性能好的副本數(shù)就調(diào)大一點(diǎn),性能差的就小一點(diǎn)。

本章主要記錄怎么為不同的節(jié)點(diǎn)使用不同的配置。

實(shí)際上是為不同的 GPU 準(zhǔn)備不同的配置。

創(chuàng)建時(shí)間片配置

同樣的創(chuàng)建 TimeSlicing 配置,不過這次 Configmap 中寫了兩個(gè)配置,而且是以 GPU 型號(hào)命名的

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 即可

    • 然后根據(jù) MIG 實(shí)例分別指定不同的 replicas 數(shù)
  • 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,這次與之前的區(qū)別在于,這里沒有指定 default 配置。

kubectl patch clusterpolicies.nvidia.com/cluster-policy \
-n gpu-operator --type merge \
-p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config-fine"}}}}'

沒有指定 default 時(shí),device-plugin 則會(huì)根據(jù) node 上的 label (nvidia.com/device-plugin.config)來獲取要使用的配置。

為節(jié)點(diǎn)打 label

在節(jié)點(diǎn)上打上下面的 label,這樣該節(jié)點(diǎn)上的 device plugin 就會(huì)根據(jù)該 label 的 value 來使用對應(yīng)名字的配置了。

比如這里,就是有這個(gè) label 的節(jié)點(diǎn)就使用名叫 tesla-t4 的配置。

kubectl label node <node-name> nvidia.com/device-plugin.config=tesla-t4

一般都是以 GPU 型號(hào)命名,然后給使用該 GPU 的節(jié)點(diǎn)都打上對應(yīng) label,這樣便于查看。

5. 關(guān)閉 TimeSlicing

想關(guān)閉 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

不出意外的話就關(guān)掉了,再次查看 Pod 信息,GPU 就變成了物理 GPU 數(shù)量,說明關(guān)閉成功。

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 是怎么實(shí)現(xiàn)的。

首先是 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

這里我們關(guān)注 resources 中的 replicas 參數(shù),正是這個(gè)參數(shù)定義了 **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 循環(huán),對 device 數(shù)量進(jìn)行了一個(gè)復(fù)制的操作,這樣每張 GPU 都可以被使用 Replicas 次了。

其他屬性都沒變,只是把 deviceID 進(jìn)行了處理,便于區(qū)分

// 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))
}

然后在真正掛載時(shí)則進(jìn)行 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 的具體實(shí)現(xiàn),其實(shí)很簡單,就是根據(jù)配置的 replicas 參數(shù)對 device plugin 感知到的設(shè)備進(jìn)行復(fù)制,并在 DeviceID 使用特定格式進(jìn)行標(biāo)記便于區(qū)分。

7. 小結(jié)

本文主要分享了 NVIDIA Time Slicing 這個(gè) GPU 共享方案,包括即實(shí)現(xiàn)原理,以及配置和使用方式。

最后通過分析源碼的方式探索了 TImeSlicing 的代碼實(shí)現(xiàn)。

為什么需要 GPU 共享、切分?

在 k8s 中使用默認(rèn) device plugin 時(shí),GPU 資源和物理 GPU 是一一對應(yīng)的,導(dǎo)致一個(gè)物理 GPU 被一個(gè) Pod 申請后,其他 Pod 就無法使用了。

為了提高資源利用率,因此我們需要 GPU 共享、切分等方案。

什么是 TimeSlicing?

TimeSlicing 是一種通過 oversubscription(超額訂閱) 來實(shí)現(xiàn) GPU 共享的策略,這種策略能讓多個(gè)任務(wù)在同一個(gè) GPU 上進(jìn)行,而不是每個(gè)任務(wù)都獨(dú)占一個(gè) GPU。

如何開啟 TimeSlicing

  • 1)創(chuàng)建 TimeSlicing 配置

    • 可以是集群統(tǒng)一配置,也可以是 Node 級(jí)別的配置,主要根據(jù)不同節(jié)點(diǎn)上的 GPU 進(jìn)行配置
    • 如果集群中所有節(jié)點(diǎn) GPU 型號(hào)都一致,則使用集群統(tǒng)一配置即可,若不一致則根據(jù) 節(jié)點(diǎn)上的 GPU 性能修改配置

    2)修改 cluster-policy,增加 TimeSlicing 相關(guān)配置

作為這兩個(gè)步驟之后,TimeSlicing 就開啟了,再次查看 Node 信息時(shí)會(huì)發(fā)現(xiàn) GPU 數(shù)量變多了。

TImeSlicing 實(shí)現(xiàn)原理

根據(jù)配置的 replicas 參數(shù)對 device plugin 感知到的設(shè)備進(jìn)行復(fù)制,并在 DeviceID 使用特定格式進(jìn)行標(biāo)記便于區(qū)分。

總結(jié)

以上是生活随笔為你收集整理的一文搞懂 GPU 共享方案: NVIDIA Time Slicing的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 丰满少妇在线观看资源站 | 中国一级片黄色一级片黄 | 日韩激情在线 | 日本不卡一区二区三区视频 | 激情导航| 成人自拍视频在线观看 | wwwjizzzcom| 极品尤物魔鬼身材啪啪仙踪林 | 国产无套粉嫩白浆内谢 | 国产成人综合av | 国产a黄| 精品人妻一区二区免费 | 美国一级大黄一片免费中文 | 国产又粗又黄的视频 | 欧美性天天影院 | 国产睡熟迷奷系列精品视频 | 日韩aa视频 | 91在线网 | 玩弄白嫩少妇xxxxx性 | 大香蕉视频一区二区 | av看片资源| 波多野结衣电车痴汉 | 日本少妇性高潮 | 国产a国产 | 99re6在线观看| 精品久久久99 | 98精品视频 | 亚洲av无码国产精品久久不卡 | 网站免费在线观看 | 亚洲一区二区在线电影 | 精品亚洲天堂 | 婷婷色在线观看 | 亚州黄色 | 天天综合人人 | 国产天堂一区 | 亚洲国产精品999 | 91视频直接看 | 成人综合婷婷国产精品久久 | 日韩在线国产精品 | 中文字幕女同女同女同 | 久久av网址 | 久久婷婷婷 | 视频一区二区三 | 国产精品乱码久久久 | 亚洲视频入口 | 亚洲一区福利视频 | 日本草草视频 | 手机在线观看av片 | 麻豆传媒在线看 | 91秦先生在线播放 | 在线免费观看不卡av | 最近免费中文字幕中文高清百度 | 草逼网站 | 麻豆av免费在线观看 | 亚洲综合在 | 欧类av怡春院 | 在线观看欧美日韩视频 | 国模少妇一区二区三区 | 久久久888 | 欧美日韩一区二区三区国产精品成人 | 无码人妻精品一区二区三区在线 | 波多野结衣中文字幕在线 | 欧美一区二区三区免费在线观看 | 日韩精品色呦呦 | 国产无套视频 | 尹人香蕉网 | 国产又大又长又粗 | 国产人成视频在线观看 | 亚洲孕交 | 国产黄色网络 | 欧美激情一二区 | 色哟哟一区二区 | 怡红院一区二区 | 三上悠亚 在线观看 | 亚洲乱轮 | 国产三级视频网站 | 激情成人综合 | 欧美专区视频 | 欧美变态视频 | 免费黄色网页 | 黑人又大又粗又长 | 最新在线黄色网址 | 久久福利视频网 | 久久久久国产免费 | 日韩欧美成人精品 | 日本嫩草影院 | 一区二区在线观看免费 | 性感av在线 | 福利二区视频 | 日韩欧美偷拍 | 欧美乱妇18p | 在线免费看黄色片 | 名校风暴在线观看免费高清完整 | 欧洲丰满少妇做爰 | 午夜欧美视频 | 中文字幕在线视频网站 | www.色就是色.com | 人人澡人人澡人人 | 精品欧美乱码久久久久久 |