Hermetyczne CUDA

Hermetic CUDA używa określonej wersji CUDA do pobrania zamiast zainstalowanej lokalnie wersji CUDA. Bazel pobierze dystrybucje CUDA, CUDNN i NCCL, a następnie użyje bibliotek i narzędzi CUDA jako zależności w różnych celach Bazel. Umożliwia to tworzenie bardziej powtarzalnych wersji w przypadku projektów uczenia maszynowego Google i obsługiwanych wersji CUDA.

Obsługiwane hermetyczne wersje CUDA i CUDNN

Obsługiwane wersje CUDA są określone w słowniku CUDA_REDIST_JSON_DICT third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

Obsługiwane wersje CUDNN są określone w pliku CUDNN_REDIST_JSON_DICT dictionary, third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

W plikach .bazelrc poszczególnych projektów zmienne środowiskowe HERMETIC_CUDA_VERSIONHERMETIC_CUDNN_VERSION są ustawione na wersje używane domyślnie, gdy w opcjach polecenia Bazel podano wartość --config=cuda.

zmienne środowiskowe kontrolujące hermetyczne wersje CUDA/CUDNN;

Zmienna środowiskowa HERMETIC_CUDA_VERSION powinna zawierać główną, podrzędną i wersję poprawki CUDA, np. 12.6.3. Zmienna środowiskowa HERMETIC_CUDNN_VERSION powinna zawierać wersję główną, podrzędną i wersję poprawki CUDNN, np. 9.3.0.

Trzy sposoby ustawiania zmiennych środowiskowych dla poleceń Bazel:

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

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

# 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.6.3"
export HERMETIC_CUDNN_VERSION="9.3.0"

Jeśli zmienne HERMETIC_CUDA_VERSIONHERMETIC_CUDNN_VERSION są nieobecne, hermetyczne reguły repozytorium CUDA/CUDNN będą wyszukiwać wartości zmiennych środowiskowych TF_CUDA_VERSIONTF_CUDNN_VERSION. Jest to konieczne ze względu na zgodność wsteczną z niehermetycznymi regułami repozytorium CUDA/CUDNN.

Mapowanie wersji CUDA i wersji dystrybucji NCCL do pobrania jest określone w pliku third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

Konfigurowanie hermetycznego CUDA

  1. W pochodzącym projekcie zależnym od XLA dodaj te wiersze do dołu pliku WORKSPACE:

    load(
       "@xla//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(
       "@xla//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(
       "@xla//third_party/gpus/cuda/hermetic:cuda_configure.bzl",
       "cuda_configure",
    )
    
    cuda_configure(name = "local_config_cuda")
    
    load(
       "@xla//third_party/nccl/hermetic:nccl_redist_init_repository.bzl",
       "nccl_redist_init_repository",
    )
    
    nccl_redist_init_repository()
    
    load(
       "@xla//third_party/nccl/hermetic:nccl_configure.bzl",
       "nccl_configure",
    )
    
    nccl_configure(name = "local_config_nccl")
    
  2. Aby wybrać konkretne wersje hermetyczne CUDA i CUDNN, odpowiednio ustaw zmienne środowiskowe HERMETIC_CUDA_VERSIONHERMETIC_CUDNN_VERSION. Używaj tylko obsługiwanych wersji. Zmienne środowiskowe możesz ustawić bezpośrednio w powłoce lub w pliku .bazelrc, jak pokazano poniżej:

    build:cuda --repo_env=HERMETIC_CUDA_VERSION="12.6.3"
    build:cuda --repo_env=HERMETIC_CUDNN_VERSION="9.3.0"
    build:cuda --repo_env=HERMETIC_CUDA_COMPUTE_CAPABILITIES="sm_50,sm_60,sm_70,sm_80,compute_90"
    
  3. Aby włączyć hermetyczną architekturę CUDA podczas wykonywania testu lub uruchamiania binarnego za pomocą bazel, dodaj do polecenia bazel flagę --@local_config_cuda//cuda:include_cuda_libs=true. Możesz podać je bezpośrednio w oprogramowaniu lub w pliku .bazelrc:

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

    Ten parametr jest potrzebny, aby mieć pewność, że zależności CUDA są prawidłowo dostarczane do testowania plików wykonywalnych. Domyślnie flaga ma wartość fałsz, aby uniknąć niechcianego połączenia pakietów Pythona wydanych przez Google z binarnymi bibliotekami CUDA.

  4. Aby wymusić tryb zgodności wstecznej CUDA, dodaj flagę --@cuda_driver//:enable_forward_compatibility=true do polecenia bazel. Możesz podać je bezpośrednio w oprogramowaniu lub w pliku .bazelrc:

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

    Wartością domyślną flagi jest false.

    Gdy tryb zgodności wstecznej CUDA jest wyłączony, cele Bazel będą używać sterowników w trybie użytkownika i trybie jądra wstępnie zainstalowanych w systemie.

    Gdy włączony jest tryb zgodności wstecznej CUDA, docelowe bazy Bazel będą używać sterownika w trybie użytkownika z ponownego rozpowszechniania sterownika CUDA pobranego do pamięci podręcznej Bazel oraz sterownika w trybie jądra wstępnie zainstalowanego w systemie. Umożliwia włączenie nowych funkcji CUDA Toolkit przy użyciu starszego sterownika w trybie jądra.

    Tryb zgodności wstecznej powinien być stosowany tylko wtedy, gdy jest to właściwe. Szczegółowe informacje znajdziesz w dokumentacji Nvidii.

Uaktualnij hermetyczną wersję CUDA/CUDNN

  1. Utwórz i prześlij prośbę o przejęcie z aktualizowanymi słownikami CUDA_REDIST_JSON_DICTCUDNN_REDIST_JSON_DICT w pliku third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

    W razie potrzeby zaktualizuj CUDA_NCCL_WHEELS w pliku third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

    W razie potrzeby zaktualizuj REDIST_VERSIONS_TO_BUILD_TEMPLATES w pliku third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

    W razie potrzeby zaktualizuj PTX_VERSION_DICT w pliku third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

  2. W przypadku każdego projektu Google ML utwórz oddzielne żądanie pull z aktualnymi wartościami HERMETIC_CUDA_VERSIONHERMETIC_CUDNN_VERSION w pliku .bazelrc.

    Wykonywanie zadań przed przesłaniem PR będzie uruchamiać testy bazel i pobierać hermetyczne dystrybucje CUDA/CUDNN. Przed przesłaniem PR sprawdź, czy zadania przed przesłaniem zostały ukończone.

  3. Aby zoptymalizować czas, niektóre konfiguracje kompilacji lub testów korzystają z lustranych wersji dystrybucji.tar. Plik json z informacjami o rozpowszechnianiu .tar w lustrzanym środowisku jest przesyłany po zaktualizowaniu plików CUDA_REDIST_JSON_DICT i CUDNN_REDIST_JSON_DICT. Pliki te można pobrać za pomocą pliku wget "https://storage.googleapis.com/mirror.tensorflow.org/developer.download.nvidia.com/compute/cuda/redist/redistrib_<cuda_version>_tar.json" w przypadku CUDA i pliku wget "https://storage.googleapis.com/mirror.tensorflow.org/developer.download.nvidia.com/compute/cudnn/redist/redistrib_<cudnn_version>_tar.json" w przypadku CUDNN. Następnie utwórz i prześlij prośbę o przeniesienie z zaktualizowanymi słownikami MIRRORED_TARS_CUDA_REDIST_JSON_DICTMIRRORED_TARS_CUDNN_REDIST_JSON_DICT w pliku third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

Wskazywanie dystrybucji CUDA/CUDNN/NCCL w lokalnym systemie plików

Jako źródła dystrybucji możesz użyć lokalnych katalogów CUDA/CUDNN/NCCL. Wymagane są te dodatkowe zmienne środowiskowe:

LOCAL_CUDA_PATH
LOCAL_CUDNN_PATH
LOCAL_NCCL_PATH

Przykład:

# 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"

Struktura folderów w katalogu CUDA powinna wyglądać tak (jakby zarchiwizowane pliki do ponownego rozpowszechniania zostały rozpakowane w jednym miejscu):

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

Struktura folderów w katalogu CUDNN powinna być następująca:

<LOCAL_CUDNN_PATH>
    include/
    lib/

Struktura folderów w katalogu NCCL powinna wyglądać tak:

<LOCAL_NCCL_PATH>
    include/
    lib/

Niestandardowe archiwa CUDA/CUDNN i koła NCCL

Dostępne są 3 opcje umożliwiające korzystanie z niestandardowych dystrybucji CUDA/CUDNN.

niestandardowe pliki JSON z rozpowszechnieniem CUDA/CUDNN.

Ta opcja umożliwia korzystanie z niestandardowych dystrybucji wszystkich zależności CUDA/CUDNN w projektach Google ML.

  1. Utwórz pliki cuda_redist.json lub cudnn_redist.json.

    cuda_redist.json wyświetlenia w formacie:

    {
       "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",
          }
       },
    }
    

    cudnn_redist.json wyświetlenia w formacie:

    {
       "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",
             }
          }
       }
    }
    

    W przypadku pełnych adresów URL i bezwzględnych ścieżek lokalnych rozpoczynających się od file:/// pole relative_path można zastąpić polem full_path.

  2. W pochodzącym projekcie zależnym od XLA zaktualizuj wywołanie hermetycznego repozytorium JSON cuda w pliku WORKSPACE. Dozwolone są zarówno linki internetowe, jak i ścieżki do plików lokalnych. Przykład:

    _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,
    )
    

    Jeśli pliki JSON zawierają ścieżki względne do dystrybucji, należy zaktualizować prefiks ścieżki w wywołaniach cuda_redist_init_repositories()cudnn_redist_init_repository(). Przykład

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

Niestandardowe dystrybucje CUDA/CUDNN

Ta opcja umożliwia korzystanie z niestandardowych dystrybucji niektórych zależności CUDA/CUDNN w projektach Google ML.

  1. W pochodzącym projekcie zależnym od XLA usuń te wiersze:

    <...>
       "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. W tym samym pliku WORKSPACE utwórz słowniki z ścieżkami dystrybucji.

    Słownik z rozkładami CUDA ma następujący format:

    _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",
          }
       },
    }
    

    Słownik z rozkładami CUDNN ma następujący format:

    _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",
             }
          }
       }
    }
    

    W przypadku pełnych adresów URL i bezwzględnych ścieżek lokalnych rozpoczynających się od file:/// pole relative_path można zastąpić polem full_path.

  3. W tym samym pliku WORKSPACE przekaż utworzone słowniki do reguły repozytorium. Jeśli słowniki zawierają ścieżki względne do dystrybucji, należy zaktualizować prefiks ścieżki w wywołaniach cuda_redist_init_repositories()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/"
    )
    

    Kombinacja powyższych opcji

W przykładzie poniżej element CUDA_REDIST_JSON_DICT jest scalany z elementem _CUDA_JSON_DICT zawierającym niestandardowe dane w formacie JSON, a element CUDNN_REDIST_JSON_DICT jest scalany z elementem _CUDNN_JSON_DICT.

Dane dystrybucji w pliku _CUDA_DIST_DICT zastępują zawartość wynikowego pliku CUDA JSON, a dane dystrybucji w pliku _CUDNN_DIST_DICT zastępują zawartość wynikowego pliku CUDNN JSON. Dane dotyczące kół NCCL są scalane z poziomu CUDA_NCCL_WHEELS_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,
)

PRZESTARZAJĄCY: nieszczelny dostęp do CUDA/CUDNN

Chociaż niehermetyczne korzystanie z CUDA/CUDNN jest wycofane, może być używane w przypadku niektórych eksperymentów, które nie są obecnie oficjalnie obsługiwane (np. tworzenie pakietów w Windows za pomocą CUDA).

Aby używać niehermetycznej wersji CUDA zainstalowanej lokalnie w projektach Google ML:

  1. Usuń wywołania do hermetycznych reguł repozytorium CUDA z pliku WORKSPACE projektu zależnego od XLA.

  2. Dodaj wywołania niehermetycznych reguł repozytorium CUDA na dole pliku WORKSPACE.

    W przypadku XLA i JAX:

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

    W przypadku TensorFlow:

    load("@local_xla//third_party/gpus:cuda_configure.bzl", "cuda_configure")
    cuda_configure(name = "local_config_cuda")
    load("@local_xla//third_party/nccl:nccl_configure.bzl", "nccl_configure")
    nccl_configure(name = "local_config_nccl")
    
  3. Ustaw te zmienne środowiskowe bezpośrednio w powłoce lub pliku .bazelrc, jak pokazano poniżej:

    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>
    

    Pamiętaj, że TF_CUDA_VERSIONTF_CUDNN_VERSION powinny zawierać tylko wersje główne i pomniejsze (np. 12.3 dla CUDA i 9.1 dla CUDNN).

  4. Teraz możesz uruchomić polecenie bazel, aby korzystać z instalacji CUDA i CUDNN na komputerze lokalnym.

    W przypadku XLA nie trzeba wprowadzać żadnych zmian w opcjach polecenia.

    W przypadku JAX użyj flagi --override_repository=tsl=<tsl_path> w opcjach polecenia Bazel.

    W przypadku Tensorflow użyj flagi --override_repository=local_tsl=<tsl_path> w opcjach polecenia Bazel.