さて、前回の続きです。前回の課題を再度考えてみたいと思います。MIGの場合には、Docker container を使わないと、インタンスを利用者からみて分離することはできませんでした。管理者に依頼して、MIG を作ってもらっても、自分の自由になるわけではなく環境変数一つでほかの利用者からの浸食が起こりえます。過去DGX-1はアプライアンスサーバーなので基本的に Workstation のように1名のユーザーが使用することを想定していますという、非常に興味深い話を伝え聞きましたが、現実的には複数の利用者で DGX (stationをのぞき)利用されています。ではどうやれば浸食を阻止できるか?という観点で、前回の MIG の試験ではいろいろ不都合が起きます。すでに他の方がその点については日本語で解説されていますので、

NVIDIA A100 MIGをLinux Deviceとして管理する - nttlabs - Medium


そこを見てもいいのですが、ここでは、DGX OS Server 5 と Nvidia DGX A100 の組み合わせでどこまでこれまでと改善されたかを見ていきたいと思います。


https://docs.nvidia.com/datacenter/tesla/mig-user-guide/index.html


DGX A100 の user manual には MIG の作り方があったのですが、最新版はなくなっており、mig-user-guide のほうに集約されたみたいです。この user guide はいずれ、/dev base nvidia capabilities が標準になるよとあったとおり、DGX OS Sever 5.0 では何も呪文を唱えなくとも、/dev based nvidia capability となっているようです。


# cat /proc/driver/nvidia-caps/mig-minors  | head -n 20
config 1
monitor 2
gpu0/gi0/access 3
gpu0/gi0/ci0/access 4
gpu0/gi0/ci1/access 5
gpu0/gi0/ci2/access 6
gpu0/gi0/ci3/access 7
gpu0/gi0/ci4/access 8
gpu0/gi0/ci5/access 9
gpu0/gi0/ci6/access 10
gpu0/gi0/ci7/access 11
gpu0/gi1/access 12
gpu0/gi1/ci0/access 13
gpu0/gi1/ci1/access 14
gpu0/gi1/ci2/access 15
gpu0/gi1/ci3/access 16
gpu0/gi1/ci4/access 17
gpu0/gi1/ci5/access 18
gpu0/gi1/ci6/access 19
gpu0/gi1/ci7/access 20
gpu0/gi2/access 21
gpu0/gi2/ci0/access 22
gpu0/gi2/ci1/access 23


とりあえず、mig user guide 通りに 2つの MIG instance を作った状態です。


root@dgxa100-01:/# nvidia-smi -L
GPU 0: A100-SXM4-40GB (UUID: GPU-f575246e-2439-4413-8435-bd71f7135f55)
  MIG 3g.20gb Device 0: (UUID: MIG-GPU-f575246e-2439-4413-8435-bd71f7135f55/1/0)
  MIG 3g.20gb Device 1: (UUID: MIG-GPU-f575246e-2439-4413-8435-bd71f7135f55/2/0)
GPU 1: A100-SXM4-40GB (UUID: GPU-eb023a54-f73b-2b08-8ea4-21df1508ea57)
GPU 2: A100-SXM4-40GB (UUID: GPU-06d5597b-7d40-bfa8-cb7a-989bb109133c)
GPU 3: A100-SXM4-40GB (UUID: GPU-f3f5c871-abbb-1df5-47bc-c2ac3f1f7bbd)
GPU 4: A100-SXM4-40GB (UUID: GPU-a14ff863-0177-ef0b-3465-c96e4a27f492)
GPU 5: A100-SXM4-40GB (UUID: GPU-f99e54f2-4a96-17d1-b901-6826d11feb3e)
GPU 6: A100-SXM4-40GB (UUID: GPU-068ae205-36e0-5747-8bdd-8bb6436faf48)
GPU 7: A100-SXM4-40GB (UUID: GPU-6b00b997-2df2-a4be-2eb0-04a9e409a859)

ではこの状況で、/dev/nvidia-caps はどう見えるかというと


root@dgxa100-01:/# ls /dev/nvidia-caps/
nvidia-cap0  nvidia-cap1  nvidia-cap12  nvidia-cap13  nvidia-cap2  nvidia-cap21  nvidia-cap22

こう見えるわけです。さて関係性が全く頭に入ってきません。もう一度、nvidia-smi の最後の行あたりを見てみると、

+-----------------------------------------------------------------------------+
| MIG devices:                                                                |
+------------------+----------------------+-----------+-----------------------+
| GPU  GI  CI  MIG |         Memory-Usage |        Vol|         Shared        |
|      ID  ID  Dev |           BAR1-Usage | SM     Unc| CE  ENC  DEC  OFA  JPG|
|                  |                      |        ECC|                       |
|==================+======================+===========+=======================|
|  0    1   0   0  |     14MiB / 20096MiB | 42      0 |  3   0    2    0    0 |
|                  |      0MiB / 32767MiB |           |                       |
+------------------+----------------------+-----------+-----------------------+
|  0    2   0   1  |     11MiB / 20096MiB | 42      0 |  3   0    2    0    0 |
|                  |      0MiB / 32767MiB |           |                       |
+------------------+----------------------+-----------+-----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

gpu 0 の gi_id 1 ci_id 0 なので、nvidia-cap13 と

gpu 0 の gi_id 2 ci_id 0 なので、nvidia-cap22 を制御すればいいのかなと思い立ちます。それでいいのか確認してみます。

cgset を使うので、cgroup-tools をインストールして確かめています。

まずテストスライスを作ってみましょう。


root@dgxa100-01:~# cgcreate -g devices:/ulgs_test
root@dgxa100-01:~# ls /sys/fs/cgroup/devices/ulgs_test/
cgroup.clone_children  cgroup.procs  devices.allow  devices.deny  devices.list  notify_on_release  tasks

nvidia-cap13 と nvidia-cap22 の device id はここでは 235 らしいので

root@dgxa100-01:~# ll /dev/nvidia-caps/
total 0
drwxr-xr-x  2 root root     180 Dec 25 12:43 ./
drwxr-xr-x 23 root root    5480 Dec 25 12:17 ../
cr--------  1 root root 235,  0 Dec 19 08:52 nvidia-cap0
cr--------  1 root root 235,  1 Dec 19 08:52 nvidia-cap1
cr--r--r--  1 root root 235, 12 Dec 25 12:19 nvidia-cap12
cr--r--r--  1 root root 235, 13 Dec 25 12:43 nvidia-cap13
cr--r--r--  1 root root 235,  2 Dec 19 08:52 nvidia-cap2
cr--r--r--  1 root root 235, 21 Dec 25 12:19 nvidia-cap21
cr--r--r--  1 root root 235, 22 Dec 25 12:43 nvidia-cap22

まずこのcap13 と cap22 の device を ulgs_test スライスで deny にしてみて、現在使用している bash のプロセス ID を cgclassif で task に割り当てて device が見えなくなるのか確認してみます。 

root@dgxa100-01:~# cgset -r devices.deny="c 235:13 rwm" ulgs_test
root@dgxa100-01:~# cgset -r devices.deny="c 235:22 rwm" ulgs_test
root@dgxa100-01:~# nvidia-smi -L
GPU 0: A100-SXM4-40GB (UUID: GPU-f575246e-2439-4413-8435-bd71f7135f55)
  MIG 3g.20gb Device 0: (UUID: MIG-GPU-f575246e-2439-4413-8435-bd71f7135f55/1/0)
  MIG 3g.20gb Device 1: (UUID: MIG-GPU-f575246e-2439-4413-8435-bd71f7135f55/2/0)
GPU 1: A100-SXM4-40GB (UUID: GPU-eb023a54-f73b-2b08-8ea4-21df1508ea57)
GPU 2: A100-SXM4-40GB (UUID: GPU-06d5597b-7d40-bfa8-cb7a-989bb109133c)
GPU 3: A100-SXM4-40GB (UUID: GPU-f3f5c871-abbb-1df5-47bc-c2ac3f1f7bbd)
GPU 4: A100-SXM4-40GB (UUID: GPU-a14ff863-0177-ef0b-3465-c96e4a27f492)
GPU 5: A100-SXM4-40GB (UUID: GPU-f99e54f2-4a96-17d1-b901-6826d11feb3e)
GPU 6: A100-SXM4-40GB (UUID: GPU-068ae205-36e0-5747-8bdd-8bb6436faf48)
GPU 7: A100-SXM4-40GB (UUID: GPU-6b00b997-2df2-a4be-2eb0-04a9e409a859)
root@dgxa100-01:~# echo $$
170320
root@dgxa100-01:~#	cgclassify	-g	devices:ulgs_test	$$
root@dgxa100-01:~# nvidia-smi -L
GPU 0: A100-SXM4-40GB (UUID: GPU-f575246e-2439-4413-8435-bd71f7135f55)
GPU 1: A100-SXM4-40GB (UUID: GPU-eb023a54-f73b-2b08-8ea4-21df1508ea57)
GPU 2: A100-SXM4-40GB (UUID: GPU-06d5597b-7d40-bfa8-cb7a-989bb109133c)
GPU 3: A100-SXM4-40GB (UUID: GPU-f3f5c871-abbb-1df5-47bc-c2ac3f1f7bbd)
GPU 4: A100-SXM4-40GB (UUID: GPU-a14ff863-0177-ef0b-3465-c96e4a27f492)
GPU 5: A100-SXM4-40GB (UUID: GPU-f99e54f2-4a96-17d1-b901-6826d11feb3e)
GPU 6: A100-SXM4-40GB (UUID: GPU-068ae205-36e0-5747-8bdd-8bb6436faf48)
GPU 7: A100-SXM4-40GB (UUID: GPU-6b00b997-2df2-a4be-2eb0-04a9e409a859)

確かにこれで見えなくなりました。そして、GPU0 以外全部見えなくしてみましょう。そして、1つだけMIG インスタンスを見せるようにすると

root@dgxa100-01:~# ll /dev/nvidia[0-9]
crw-rw-rw- 1 root root 195, 0 Dec 19 08:52 /dev/nvidia0
crw-rw-rw- 1 root root 195, 1 Dec 19 08:52 /dev/nvidia1
crw-rw-rw- 1 root root 195, 2 Dec 19 08:52 /dev/nvidia2
crw-rw-rw- 1 root root 195, 3 Dec 19 08:52 /dev/nvidia3
crw-rw-rw- 1 root root 195, 4 Dec 19 08:52 /dev/nvidia4
crw-rw-rw- 1 root root 195, 5 Dec 19 08:52 /dev/nvidia5
crw-rw-rw- 1 root root 195, 6 Dec 19 08:52 /dev/nvidia6
crw-rw-rw- 1 root root 195, 7 Dec 19 08:52 /dev/nvidia7
root@dgxa100-01:~# cgset -r devices.deny="c 195:1 rwm" ulgs_test
root@dgxa100-01:~# cgset -r devices.deny="c 195:2 rwm" ulgs_test
root@dgxa100-01:~# cgset -r devices.deny="c 195:3 rwm" ulgs_test
root@dgxa100-01:~# cgset -r devices.deny="c 195:4 rwm" ulgs_test
root@dgxa100-01:~# cgset -r devices.deny="c 195:5 rwm" ulgs_test
root@dgxa100-01:~# cgset -r devices.deny="c 195:6 rwm" ulgs_test
root@dgxa100-01:~# cgset -r devices.deny="c 195:7 rwm" ulgs_test
root@dgxa100-01:~# nvidia-smi -L
GPU 0: A100-SXM4-40GB (UUID: GPU-f575246e-2439-4413-8435-bd71f7135f55)
root@dgxa100-01:~# cgset -r devices.allow="c 235:22 rwm" ulgs_test
root@dgxa100-01:~# nvidia-smi -L
GPU 0: A100-SXM4-40GB (UUID: GPU-f575246e-2439-4413-8435-bd71f7135f55)
  MIG 3g.20gb Device 0: (UUID: MIG-GPU-f575246e-2439-4413-8435-bd71f7135f55/2/0)

これで基本的な cgroup devices の制御構造はわかりましたので、Altair(Univa)GE で動かしてみようと思うのですが、現時点ではAltair(Univa)GE はこの話に対応してませんので、ちょっと考えて修正スクリプトを入れて実行してみると



一応、ひとつづつ分離して見せることはできました。これで、Slurm ではできないDocker ジョブの分離も通常ジョブも Altair(U)GEをつかえば、MIG で分離して使用できるようになりました。

GPU0 と MIG インスタンスが双方見えているこの状態で、なにか cuda を使ったプロセスを走らせてみて


nvidia-smi を取ってみると



確かに、1つのMIG インタンスだけを使ってプロセスが流れていることがわかりました。Slurm でも non docker ジョブであれば管理できると書かれているので、おそらくできるのでしょう。ただ、DGX A100 + MIG を利用するのであれば、本命は k8s ではないかと思います。ジョブ単位でコンテナを処理するほうがいいのか、コンテナをインスタンス単位で常時稼働をするのがいいのか、開発・運用ステージによりその運用は異なってくるとおもわれます。k8s への対応は

https://github.com/NVIDIA/k8s-device-plugin

が存在しており、すでに MIG にも対応しています。そうしないと Triton Inference Server は構築できないでしょうから。

残念ながら、簡易 k8s ではこのあたりの対応が遅れているように思えます。単体で動作する microk8s や k3s とかは便利なのですが、そのあたりがユーザーや開発者の数に比例して整備が遅れているように見えます。今の段階では本物の k8s を構築するほかなさそうで、そうなると、DGX 単体では構築が難しくなります。いつかテストしてみたいですね。


MIG のトピックはこれで終わりになりますので、次は Clara に戻るか、Ubuntu の話をしてみたいと思います。