Ringkasan Hermetic CUDA

CUDA Hermetic menggunakan versi CUDA tertentu yang dapat didownload, bukan CUDA yang diinstal secara lokal oleh pengguna. Bazel akan mendownload distribusi CUDA, CUDNN, dan NCCL, lalu menggunakan library dan alat CUDA sebagai dependensi dalam berbagai target Bazel. Hal ini memungkinkan build yang lebih dapat direproduksi untuk project Google ML dan versi CUDA yang didukung.

Versi CUDA, CUDNN hermetic yang didukung

Versi CUDA yang didukung ditentukan dalam kamus CUDA_REDIST_JSON_DICT, third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

Versi CUDNN yang didukung ditentukan di kamus CUDNN_REDIST_JSON_DICT, third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

File .bazelrc dari setiap project memiliki variabel lingkungan HERMETIC_CUDA_VERSION, HERMETIC_CUDNN_VERSION yang ditetapkan ke versi yang digunakan secara default saat --config=cuda ditentukan dalam opsi perintah Bazel.

Variabel lingkungan yang mengontrol versi CUDA/CUDNN hermetis

Variabel lingkungan HERMETIC_CUDA_VERSION harus terdiri dari versi CUDA utama, minor, dan patch, misalnya 12.3.2. Variabel lingkungan HERMETIC_CUDNN_VERSION harus terdiri dari versi CUDNN utama, minor, dan patch, misalnya 9.1.1.

Tiga cara menetapkan variabel lingkungan untuk perintah Bazel:

# Add an entry to your `.bazelrc` file
build:cuda --repo_env=HERMETIC_CUDA_VERSION="12.3.2"
build:cuda --repo_env=HERMETIC_CUDNN_VERSION="9.1.1"

# OR pass it directly to your specific build command
bazel build --config=cuda <target> \
--repo_env=HERMETIC_CUDA_VERSION="12.3.2" \
--repo_env=HERMETIC_CUDNN_VERSION="9.1.1"

# If .bazelrc doesn't have corresponding entries and the environment variables
# are not passed to bazel command, you can set them globally in your shell:
export HERMETIC_CUDA_VERSION="12.3.2"
export HERMETIC_CUDNN_VERSION="9.1.1"

Jika HERMETIC_CUDA_VERSION dan HERMETIC_CUDNN_VERSION tidak ada, aturan repositori CUDA/CUDNN hermetik akan mencari nilai variabel lingkungan TF_CUDA_VERSION dan TF_CUDNN_VERSION. Hal ini dibuat untuk kompatibilitas mundur dengan aturan repositori CUDA/CUDNN non-hermetis.

Pemetaan antara versi CUDA dan versi distribusi NCCL yang akan didownload ditentukan di third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl

Mengonfigurasi CUDA hermetis

  1. Dalam project downstream yang bergantung pada XLA, tambahkan baris berikut ke bagian bawah file WORKSPACE:

    load(
       "@tsl//third_party/gpus/cuda/hermetic:cuda_json_init_repository.bzl",
       "cuda_json_init_repository",
    )
    
    cuda_json_init_repository()
    
    load(
       "@cuda_redist_json//:distributions.bzl",
       "CUDA_REDISTRIBUTIONS",
       "CUDNN_REDISTRIBUTIONS",
    )
    load(
       "@tsl//third_party/gpus/cuda/hermetic:cuda_redist_init_repositories.bzl",
       "cuda_redist_init_repositories",
       "cudnn_redist_init_repository",
    )
    
    cuda_redist_init_repositories(
       cuda_redistributions = CUDA_REDISTRIBUTIONS,
    )
    
    cudnn_redist_init_repository(
       cudnn_redistributions = CUDNN_REDISTRIBUTIONS,
    )
    
    load(
       "@tsl//third_party/gpus/cuda/hermetic:cuda_configure.bzl",
       "cuda_configure",
    )
    
    cuda_configure(name = "local_config_cuda")
    
    load(
       "@tsl//third_party/nccl/hermetic:nccl_redist_init_repository.bzl",
       "nccl_redist_init_repository",
    )
    
    nccl_redist_init_repository()
    
    load(
       "@tsl//third_party/nccl/hermetic:nccl_configure.bzl",
       "nccl_configure",
    )
    
    nccl_configure(name = "local_config_nccl")
    
  2. Untuk memilih versi CUDA dan CUDNN hermetis tertentu, tetapkan variabel lingkungan HERMETIC_CUDA_VERSION dan HERMETIC_CUDNN_VERSION. Hanya gunakan versi yang didukung. Anda dapat menetapkan variabel lingkungan langsung di shell atau dalam file .bazelrc seperti yang ditunjukkan di bawah:

    build:cuda --repo_env=HERMETIC_CUDA_VERSION="12.3.2"
    build:cuda --repo_env=HERMETIC_CUDNN_VERSION="9.1.1"
    build:cuda --repo_env=HERMETIC_CUDA_COMPUTE_CAPABILITIES="sm_50,sm_60,sm_70,sm_80,compute_90"
    
  3. Untuk mengaktifkan CUDA hermetis selama eksekusi pengujian, atau saat menjalankan biner melalui bazel, pastikan untuk menambahkan flag --@local_config_cuda//cuda:include_cuda_libs=true ke perintah bazel Anda. Anda dapat memberikannya langsung di shell atau di .bazelrc:

    build:cuda --@local_config_cuda//cuda:include_cuda_libs=true
    

    Flag ini diperlukan untuk memastikan bahwa dependensi CUDA disediakan dengan benar untuk menguji file yang dapat dieksekusi. Flag ini bernilai salah secara default untuk menghindari penggabungan yang tidak diinginkan dari wheel Python yang dirilis Google ke biner CUDA.

  4. Untuk menerapkan mode kompatibilitas maju CUDA, tambahkan flag --@cuda_driver//:enable_forward_compatibility=true ke perintah bazel Anda. Anda dapat menyediakannya secara langsung di shell atau di .bazelrc:

    test:cuda --@cuda_driver//:enable_forward_compatibility=true
    

    Nilai flag default adalah false.

    Jika mode kompatibilitas maju CUDA dinonaktifkan, target Bazel akan menggunakan Driver Mode Pengguna dan Mode Kernel yang diprainstal di sistem.

    Saat mode kompatibilitas maju CUDA diaktifkan, target Bazel akan menggunakan Driver Mode Pengguna dari pendistribusian ulang driver CUDA yang didownload ke cache Bazel dan Driver Mode Kernel yang telah diinstal sebelumnya pada sistem. Hal ini memungkinkan pengaktifan fitur CUDA Toolkit baru saat menggunakan Kernel Mode Driver yang lebih lama.

    Mode kompatibilitas maju hanya boleh diterapkan jika sesuai - lihat dokumentasi NVIDIA untuk mengetahui detailnya.

Mengupgrade versi CUDA/CUDNN hermetis

  1. Buat dan kirim permintaan pull dengan kamus CUDA_REDIST_JSON_DICT, CUDA_REDIST_JSON_DICT yang diperbarui di third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

    Perbarui CUDA_NCCL_WHEELS di third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl jika diperlukan.

    Update REDIST_VERSIONS_TO_BUILD_TEMPLATES di third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl jika perlu.

  2. Untuk setiap project Google ML, buat permintaan pull terpisah dengan HERMETIC_CUDA_VERSION dan HERMETIC_CUDNN_VERSION yang diperbarui dalam file .bazelrc.

    Eksekusi tugas pra-pengiriman PR akan meluncurkan pengujian bazel dan mendownload distribusi CUDA/CUDNN hermetis. Verifikasi bahwa tugas pra-pengiriman lulus sebelum mengirimkan PR.

Menunjuk ke redistribusi CUDA/CUDNN/NCCL di sistem file lokal

Anda dapat menggunakan direktori CUDA/CUDNN/NCCL lokal sebagai sumber distribusi ulang. Variabel lingkungan tambahan berikut diperlukan:

LOCAL_CUDA_PATH
LOCAL_CUDNN_PATH
LOCAL_NCCL_PATH

Contoh:

# Add an entry to your `.bazelrc` file
build:cuda --repo_env=LOCAL_CUDA_PATH="/foo/bar/nvidia/cuda"
build:cuda --repo_env=LOCAL_CUDNN_PATH="/foo/bar/nvidia/cudnn"
build:cuda --repo_env=LOCAL_NCCL_PATH="/foo/bar/nvidia/nccl"

# OR pass it directly to your specific build command
bazel build --config=cuda <target> \
--repo_env=LOCAL_CUDA_PATH="/foo/bar/nvidia/cuda" \
--repo_env=LOCAL_CUDNN_PATH="/foo/bar/nvidia/cudnn" \
--repo_env=LOCAL_NCCL_PATH="/foo/bar/nvidia/nccl"

# If .bazelrc doesn't have corresponding entries and the environment variables
# are not passed to bazel command, you can set them globally in your shell:
export LOCAL_CUDA_PATH="/foo/bar/nvidia/cuda"
export LOCAL_CUDNN_PATH="/foo/bar/nvidia/cudnn"
export LOCAL_NCCL_PATH="/foo/bar/nvidia/nccl"

Struktur folder di dalam direktori CUDA harus seperti berikut (seolah-olah redistribusi yang diarsipkan diekstrak ke satu tempat):

<LOCAL_CUDA_PATH>/
    include/
    bin/
    lib/
    nvvm/

Struktur folder di dalam direktori CUDNN harus sebagai berikut:

<LOCAL_CUDNN_PATH>
    include/
    lib/

Struktur folder di dalam direktori NCCL harus seperti berikut:

<LOCAL_NCCL_PATH>
    include/
    lib/

Arsip CUDA/CUDNN kustom dan wheel NCCL

Ada tiga opsi yang memungkinkan penggunaan distribusi CUDA/CUDNN kustom.

File JSON distribusi ulang CUDA/CUDNN kustom

Opsi ini memungkinkan penggunaan distribusi kustom untuk semua dependensi CUDA/CUDNN dalam project ML Google.

  1. Buat file cuda_redist.json dan/atau cudnn_redist.json.

    Acara cuda_redist.json mengikuti format di bawah ini:

    {
       "cuda_cccl": {
          "linux-x86_64": {
             "relative_path": "cuda_cccl-linux-x86_64-12.4.99-archive.tar.xz",
          },
          "linux-sbsa": {
             "relative_path": "cuda_cccl-linux-sbsa-12.4.99-archive.tar.xz",
          }
       },
    }
    

    Acara cudnn_redist.json mengikuti format di bawah ini:

    {
       "cudnn": {
          "linux-x86_64": {
             "cuda12": {
             "relative_path": "cudnn/linux-x86_64/cudnn-linux-x86_64-9.0.0.312_cuda12-archive.tar.xz",
             }
          },
          "linux-sbsa": {
             "cuda12": {
             "relative_path": "cudnn/linux-sbsa/cudnn-linux-sbsa-9.0.0.312_cuda12-archive.tar.xz",
             }
          }
       }
    }
    

    Kolom relative_path dapat diganti dengan full_path untuk URL lengkap dan jalur lokal absolut yang dimulai dengan file:///.

  2. Dalam project downstream yang bergantung pada XLA, perbarui panggilan repositori JSON cuda hermetis dalam file WORKSPACE. Link web dan jalur file lokal diizinkan. Contoh:

    _CUDA_JSON_DICT = {
       "12.4.0": [
          "file:///home/user/Downloads/redistrib_12.4.0_updated.json",
       ],
    }
    
    _CUDNN_JSON_DICT = {
       "9.0.0": [
          "https://developer.download.nvidia.com/compute/cudnn/redist/redistrib_9.0.0.json",
       ],
    }
    
    cuda_json_init_repository(
       cuda_json_dict = _CUDA_JSON_DICT,
       cudnn_json_dict = _CUDNN_JSON_DICT,
    )
    

    Jika file JSON berisi jalur relatif ke distribusi, awalan jalur harus diperbarui dalam panggilan cuda_redist_init_repositories() dan cudnn_redist_init_repository(). Contoh

    cuda_redist_init_repositories(
       cuda_redistributions = CUDA_REDISTRIBUTIONS,
       cuda_redist_path_prefix = "file:///usr/Downloads/dists/",
    )
    

Distribusi CUDA/CUDNN kustom

Opsi ini memungkinkan penggunaan distribusi kustom untuk beberapa dependensi CUDA/CUDNN dalam project Google ML.

  1. Di project downstream yang bergantung pada XLA, hapus baris di bawah ini:

    <...>
       "CUDA_REDIST_JSON_DICT",
    <...>
       "CUDNN_REDIST_JSON_DICT",
    <...>
    
    cuda_json_init_repository(
       cuda_json_dict = CUDA_REDIST_JSON_DICT,
       cudnn_json_dict = CUDNN_REDIST_JSON_DICT,
    )
    
    load(
       "@cuda_redist_json//:distributions.bzl",
       "CUDA_REDISTRIBUTIONS",
       "CUDNN_REDISTRIBUTIONS",
    )
    
  2. Dalam file WORKSPACE yang sama, buat kamus dengan jalur distribusi.

    Kamus dengan distribusi CUDA ditampilkan mengikuti format di bawah ini:

    _CUSTOM_CUDA_REDISTRIBUTIONS = {
       "cuda_cccl": {
          "linux-x86_64": {
             "relative_path": "cuda_cccl-linux-x86_64-12.4.99-archive.tar.xz",
          },
          "linux-sbsa": {
             "relative_path": "cuda_cccl-linux-sbsa-12.4.99-archive.tar.xz",
          }
       },
    }
    

    Kamus dengan distribusi CUDNN menampilkan format berikut:

    _CUSTOM_CUDNN_REDISTRIBUTIONS = {
       "cudnn": {
          "linux-x86_64": {
             "cuda12": {
             "relative_path": "cudnn/linux-x86_64/cudnn-linux-x86_64-9.0.0.312_cuda12-archive.tar.xz",
             }
          },
          "linux-sbsa": {
             "cuda12": {
             "relative_path": "cudnn/linux-sbsa/cudnn-linux-sbsa-9.0.0.312_cuda12-archive.tar.xz",
             }
          }
       }
    }
    

    Kolom relative_path dapat diganti dengan full_path untuk URL lengkap dan jalur lokal absolut yang dimulai dengan file:///.

  3. Dalam file WORKSPACE yang sama, teruskan kamus yang dibuat ke aturan repositori. Jika kamus berisi jalur relatif ke distribusi, awalan jalur harus diperbarui dalam panggilan cuda_redist_init_repositories() dan cudnn_redist_init_repository().

    cuda_redist_init_repositories(
       cuda_redistributions = _CUSTOM_CUDA_REDISTRIBUTIONS,
       cuda_redist_path_prefix = "file:///home/usr/Downloads/dists/",
    )
    
    cudnn_redist_init_repository(
       cudnn_redistributions = _CUSTOM_CUDNN_REDISTRIBUTIONS,
       cudnn_redist_path_prefix = "file:///home/usr/Downloads/dists/cudnn/"
    )
    

    Kombinasi opsi di atas

Pada contoh di bawah, CUDA_REDIST_JSON_DICT digabungkan dengan data JSON kustom di _CUDA_JSON_DICT, dan CUDNN_REDIST_JSON_DICT digabungkan dengan _CUDNN_JSON_DICT.

Data distribusi di _CUDA_DIST_DICT akan menggantikan konten file JSON CUDA yang dihasilkan, dan data distribusi di _CUDNN_DIST_DICT akan menggantikan konten file JSON CUDNN yang dihasilkan. Data roda NCCL digabungkan dari CUDA_NCCL_WHEELS dan _NCCL_WHEEL_DICT.

load(
    //third_party/gpus/cuda/hermetic:cuda_redist_versions.bzl",
    "CUDA_REDIST_PATH_PREFIX",
    "CUDA_NCCL_WHEELS",
    "CUDA_REDIST_JSON_DICT",
    "CUDNN_REDIST_PATH_PREFIX",
    "CUDNN_REDIST_JSON_DICT",
)

_CUDA_JSON_DICT = {
   "12.4.0": [
      "file:///usr/Downloads/redistrib_12.4.0_updated.json",
   ],
}

_CUDNN_JSON_DICT = {
   "9.0.0": [
      "https://developer.download.nvidia.com/compute/cudnn/redist/redistrib_9.0.0.json",
   ],
}

cuda_json_init_repository(
   cuda_json_dict = CUDA_REDIST_JSON_DICT | _CUDA_JSON_DICT,
   cudnn_json_dict = CUDNN_REDIST_JSON_DICT | _CUDNN_JSON_DICT,
)

load(
   "@cuda_redist_json//:distributions.bzl",
   "CUDA_REDISTRIBUTIONS",
   "CUDNN_REDISTRIBUTIONS",
)

load(
   "//third_party/gpus/cuda/hermetic:cuda_redist_init_repositories.bzl",
   "cuda_redist_init_repositories",
   "cudnn_redist_init_repository",
)

_CUDA_DIST_DICT = {
   "cuda_cccl": {
      "linux-x86_64": {
            "relative_path": "cuda_cccl-linux-x86_64-12.4.99-archive.tar.xz",
      },
      "linux-sbsa": {
            "relative_path": "cuda_cccl-linux-sbsa-12.4.99-archive.tar.xz",
      },
   },
   "libcusolver": {
      "linux-x86_64": {
            "full_path": "file:///usr/Downloads/dists/libcusolver-linux-x86_64-11.6.0.99-archive.tar.xz",
      },
      "linux-sbsa": {
         "relative_path": "libcusolver-linux-sbsa-11.6.0.99-archive.tar.xz",
      },
   },
}

_CUDNN_DIST_DICT = {
   "cudnn": {
      "linux-x86_64": {
            "cuda12": {
               "relative_path": "cudnn-linux-x86_64-9.0.0.312_cuda12-archive.tar.xz",
            },
      },
      "linux-sbsa": {
            "cuda12": {
               "relative_path": "cudnn-linux-sbsa-9.0.0.312_cuda12-archive.tar.xz",
            },
      },
   },
}

cudnn_redist_init_repositories(
   cuda_redistributions = CUDA_REDISTRIBUTIONS | _CUDA_DIST_DICT,
   cuda_redist_path_prefix = "file:///usr/Downloads/dists/",
)

cudnn_redist_init_repository(
   cudnn_redistributions = CUDNN_REDISTRIBUTIONS | _CUDNN_DIST_DICT,
   cudnn_redist_path_prefix = "file:///usr/Downloads/dists/cudnn/"
)

load(
    "//third_party/nccl/hermetic:nccl_redist_init_repository.bzl",
    "nccl_redist_init_repository",
)

_NCCL_WHEEL_DICT = {
   "12.4.0": {
      "x86_64-unknown-linux-gnu": {
            "url": "https://files.pythonhosted.org/packages/38/00/d0d4e48aef772ad5aebcf70b73028f88db6e5640b36c38e90445b7a57c45/nvidia_nccl_cu12-2.19.3-py3-none-manylinux1_x86_64.whl",
      },
   },
}

nccl_redist_init_repository(
   cuda_nccl_wheels = CUDA_NCCL_WHEELS | _NCCL_WHEEL_DICT,
)

TIDAK DIGUNAKAN LAGI: Penggunaan CUDA/CUDNN non-hermetis

Meskipun penggunaan CUDA/CUDNN non-hermetis tidak digunakan lagi, penggunaan ini dapat digunakan untuk beberapa eksperimen yang saat ini tidak didukung secara resmi (misalnya, mem-build wheel di Windows dengan CUDA).

Berikut adalah langkah-langkah untuk menggunakan CUDA non-hermetik yang diinstal secara lokal di project ML Google:

  1. Hapus panggilan ke aturan repositori CUDA hermetis dari file WORKSPACE project yang bergantung pada XLA.

  2. Tambahkan panggilan ke aturan repositori CUDA non-hermetis ke bagian bawah file WORKSPACE.

    Untuk XLA dan JAX:

    load("@tsl//third_party/gpus:cuda_configure.bzl", "cuda_configure")
    cuda_configure(name = "local_config_cuda")
    load("@tsl//third_party/nccl:nccl_configure.bzl", "nccl_configure")
    nccl_configure(name = "local_config_nccl")
    

    Untuk Tensorflow:

    load("@local_tsl//third_party/gpus:cuda_configure.bzl", "cuda_configure")
    cuda_configure(name = "local_config_cuda")
    load("@local_tsl//third_party/nccl:nccl_configure.bzl", "nccl_configure")
    nccl_configure(name = "local_config_nccl")
    
  3. Tetapkan variabel lingkungan berikut langsung di shell Anda atau dalam file .bazelrc seperti yang ditunjukkan di bawah:

    build:cuda --action_env=TF_CUDA_VERSION=<locally installed cuda version>
    build:cuda --action_env=TF_CUDNN_VERSION=<locally installed cudnn version>
    build:cuda --action_env=TF_CUDA_COMPUTE_CAPABILITIES=<CUDA compute capabilities>
    build:cuda --action_env=LD_LIBRARY_PATH=<CUDA/CUDNN libraries folder locations divided by : sign>
    build:cuda --action_env=CUDA_TOOLKIT_PATH=<preinstalled CUDA folder location>
    build:cuda --action_env=TF_CUDA_PATHS=<preinstalled CUDA/CUDNN folder locations divided by , sign>
    build:cuda --action_env=NCCL_INSTALL_PATH=<preinstalled NCCL library folder location>
    

    Perhatikan bahwa TF_CUDA_VERSION dan TF_CUDNN_VERSION hanya boleh terdiri dari versi utama dan minor (misalnya, 12.3 untuk CUDA dan 9.1 untuk CUDNN).

  4. Sekarang Anda dapat menjalankan perintah bazel untuk menggunakan CUDA dan CUDNN yang diinstal secara lokal.

    Untuk XLA, tidak diperlukan perubahan pada opsi perintah.

    Untuk JAX, gunakan flag --override_repository=tsl=<tsl_path> dalam opsi perintah Bazel.

    Untuk Tensorflow, gunakan flag --override_repository=local_tsl=<tsl_path> pada opsi perintah Bazel.