Panoramica di CUDA ermetico

CUDA ermetico utilizza una specifica versione scaricabile di CUDA anziché CUDA installato localmente dell'utente. Bazel scaricherà le distribuzioni CUDA, CUDNN e NCCL, e poi utilizzerà le librerie e gli strumenti CUDA come dipendenze in vari target Bazel. Ciò consente build più riproducibili per i progetti Google ML e le versioni CUDA supportate.

Versioni CUDA e CUDNN in isolamento supportate

Le versioni CUDA supportate sono specificate nel CUDA_REDIST_JSON_DICT dizionario, third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

Le versioni CUDNN supportate sono specificate nel CUDNN_REDIST_JSON_DICT dizionario, third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

I file .bazelrc dei singoli progetti hanno le variabili di ambiente HERMETIC_CUDA_VERSION, HERMETIC_CUDNN_VERSION impostate sulle versioni utilizzate per default quando --config=cuda è specificato nelle opzioni del comando Bazel.

Variabili di ambiente che controllano le versioni ermetiche CUDA/CUDNN

La variabile di ambiente HERMETIC_CUDA_VERSION deve essere composta dalla versione principale, secondaria e patch di CUDA, ad esempio 12.3.2. La variabile di ambiente HERMETIC_CUDNN_VERSION deve essere composta dalla versione principale, secondaria e patch di CUDNN, ad esempio 9.1.1.

Tre modi per impostare le variabili di ambiente per i comandi 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"

Se HERMETIC_CUDA_VERSION e HERMETIC_CUDNN_VERSION non sono presenti, le regole del repository CUDA/CUDNN ermetico cercheranno i valori delle variabili di ambiente TF_CUDA_VERSION e TF_CUDNN_VERSION. Questo è fatto per la compatibilità con le regole del repository CUDA/CUDNN non ermetico.

La mappatura tra la versione CUDA e la versione di distribuzione NCCL da scaricare è specificata in third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl

Configura CUDA ermetico

  1. Nel progetto a valle dipendente da XLA, aggiungi le seguenti righe alla fine del 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. Per selezionare versioni specifiche di CUDA e CUDNN ermetici, imposta rispettivamente le variabili di ambiente HERMETIC_CUDA_VERSION e HERMETIC_CUDNN_VERSION. Utilizza solo le versioni supportate. Puoi impostare le variabili di ambiente direttamente nella shell o nel file .bazelrc come mostrato di seguito:

    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. Per attivare CUDA ermetico durante l'esecuzione del test o quando esegui un file binario tramite bazel, assicurati di aggiungere il flag --@local_config_cuda//cuda:include_cuda_libs=true al comando bazel. Puoi fornirla direttamente in una shell o in .bazelrc:

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

    Il flag è necessario per verificare che le dipendenze CUDA siano fornite correttamente per testare gli eseguibili. Il flag è False per impostazione predefinita per evitare l'accoppiamento indesiderato delle ruote Python rilasciate da Google ai binari CUDA.

  4. Per applicare la modalità di compatibilità futura di CUDA, aggiungi il flag --@cuda_driver//:enable_forward_compatibility=true al comando bazel. Puoi fornirlo direttamente in una shell o in .bazelrc:

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

    Il valore predefinito del flag è false.

    Quando la modalità di compatibilità con forwarding CUDA è disabilitata, le destinazioni Bazel utilizzeranno i driver Modalità utente e modalità kernel preinstallati nel sistema.

    Quando la modalità di compatibilità futura di CUDA è attivata, i target Bazel utilizzeranno il driver in modalità utente della ridistribuzione del driver CUDA scaricato nella cache di Bazel e il driver in modalità kernel preinstallato nel sistema. Consente di abilitare le nuove funzionalità di CUDA Toolkit durante l'uso di un driver in modalità kernel precedente.

    La modalità di compatibilità futura deve essere applicata solo quando è opportuno. Per maggiori dettagli, consulta la documentazione di NVIDIA.

Esegui l'upgrade della versione ermetica CUDA/CUDNN

  1. Crea e invia una richiesta di pull con i dizionari CUDA_REDIST_JSON_DICT e CUDA_REDIST_JSON_DICT aggiornati in third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl.

    Aggiorna CUDA_NCCL_WHEELS in third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl se necessario.

    Aggiorna REDIST_VERSIONS_TO_BUILD_TEMPLATES in third_party/gpus/cuda/hermetic/cuda_redist_versions.bzl se necessario.

  2. Per ogni progetto Google ML, crea una richiesta pull separata con HERMETIC_CUDA_VERSION e HERMETIC_CUDNN_VERSION aggiornati nel file .bazelrc.

    Le esecuzioni del job di pre-invio PR avvieranno i test del bazel e scaricheranno le distribuzioni ermetiche CUDA/CUDNN. Verifica che i job di pre-invio siano stati superati prima di inviare la RP.

Riferimento alle ridistribuzione di CUDA/CUDNN/NCCL sul file system locale

Puoi utilizzare le directory CUDA/CUDNN/NCCL locali come origine di ridistribuzione. Sono necessarie le seguenti variabili di ambiente aggiuntive:

LOCAL_CUDA_PATH
LOCAL_CUDNN_PATH
LOCAL_NCCL_PATH

Esempio:

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

La struttura delle cartelle all'interno della directory CUDA dovrebbe essere la seguente (come se le ridistribuzione archiviate fossero scomposte in un'unica posizione):

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

La struttura delle cartelle all'interno della directory CUDNN dovrebbe essere la seguente:

<LOCAL_CUDNN_PATH>
    include/
    lib/

La struttura delle cartelle all'interno della directory NCCL dovrebbe essere la seguente:

<LOCAL_NCCL_PATH>
    include/
    lib/

Archivi CUDA/CUDNN personalizzati e ruote NCCL

Esistono tre opzioni che consentono l'utilizzo di distribuzioni CUDA/CUDNN personalizzate.

File JSON di ridistribuzione CUDA/CUDNN personalizzati

Questa opzione consente di utilizzare distribuzioni personalizzate per tutte le dipendenze CUDA/CUDNN nei progetti di machine learning di Google.

  1. Crea file cuda_redist.json e/o cudnn_redist.json.

    I programmi cuda_redist.json devono seguire il formato riportato di seguito:

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

    I programmi cudnn_redist.json devono seguire il formato riportato di seguito:

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

    Il campo relative_path può essere sostituito con full_path per gli URL completi e i percorsi locali assoluti che iniziano con file:///.

  2. Nel progetto downstream dipendente da XLA, aggiorna la chiamata al repository JSON cuda ermetica nel file WORKSPACE. Sono consentiti sia i link web sia i percorsi file locali. Esempio:

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

    Se i file JSON contengono percorsi relativi alle distribuzioni, il prefisso del percorso deve essere aggiornato nelle chiamate cuda_redist_init_repositories() e cudnn_redist_init_repository(). Esempio

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

Distribuzioni CUDA/CUDNN personalizzate

Questa opzione consente di utilizzare distribuzioni personalizzate per alcune dipendenze CUDA/CUDNN nei progetti di machine learning di Google.

  1. Nel progetto a valle dipendente da XLA, rimuovi le righe seguenti:

    <...>
       "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. Nello stesso file WORKSPACE, crea i dizionari con i percorsi di distribuzione.

    Il dizionario con le distribuzioni CUDA segue il seguente formato:

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

    Il dizionario con le distribuzioni CUDNN segue il formato riportato di seguito:

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

    Il campo relative_path può essere sostituito con full_path per gli URL completi e i percorsi locali assoluti che iniziano con file:///.

  3. Nello stesso file WORKSPACE, passa i dizionari creati alla regola del repository. Se i dizionari contengono percorsi relativi alle distribuzioni, il prefisso del percorso deve essere aggiornato nelle chiamate cuda_redist_init_repositories() e 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/"
    )
    

    Combinazione delle opzioni precedenti

Nell'esempio seguente, CUDA_REDIST_JSON_DICT viene unito ai dati JSON personalizzati in _CUDA_JSON_DICT e CUDNN_REDIST_JSON_DICT viene unito a _CUDNN_JSON_DICT.

I dati delle distribuzioni in _CUDA_DIST_DICT eseguono l'override dei contenuti del file JSON CUDA risultante, mentre i dati delle distribuzioni in _CUDNN_DIST_DICT sostituiscono i contenuti del file JSON CUDNN risultante. I dati sulle ruote NCCL vengono uniti da CUDA_NCCL_WHEELS e _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,
)

NON PIU' DISPONIBILE: utilizzo di CUDA/CUDNN non ermetico

Sebbene l'utilizzo di CUDA/CUDNN non ermetico sia deprecato, potrebbe essere utilizzato per alcuni esperimenti attualmente non supportati ufficialmente (ad esempio, la creazione di wheel su Windows con CUDA).

Ecco i passaggi per utilizzare CUDA non ermetico installato localmente nei progetti di Google ML:

  1. Elimina le chiamate alle regole del repository CUDA ermetico dal WORKSPACE file del progetto dipendente da XLA.

  2. Aggiungi le chiamate alle regole del repository CUDA non ermetico alla fine del WORKSPACE file.

    Per XLA e 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")
    

    Per 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. Imposta le seguenti variabili di ambiente direttamente nella shell o nel .bazelrc file come mostrato di seguito:

    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>
    

    Tieni presente che TF_CUDA_VERSION e TF_CUDNN_VERSION devono essere costituiti solo da versioni principali e secondarie (ad es. 12.3 per CUDA e 9.1 per CUDNN).

  4. Ora puoi eseguire il comando bazel per utilizzare CUDA e CUDNN installati localmente.

    Per XLA, non sono necessarie modifiche alle opzioni di comando.

    Per JAX, utilizza il flag --override_repository=tsl=<tsl_path> nelle opzioni del comando Bazel.

    Per TensorFlow, utilizza il flag --override_repository=local_tsl=<tsl_path> nelle opzioni del comando Bazel.