Usa una imagen de SO personalizada
Puedes usar una imagen de SO personalizada para tus VMs de TPU y precargar software, usar una distribución de SO específica o aplicar modificaciones personalizadas del kernel. Crear una imagen personalizada implica realizar modificaciones específicas del sistema durante el proceso de creación de la imagen y configurar la imagen para que controle las tareas de tiempo de arranque necesarias para la funcionalidad de la TPU.
Ten en cuenta las siguientes renuncias de responsabilidad si usas una imagen de SO personalizada con TPU:
- Google proporciona imágenes predeterminadas de Ubuntu con asistencia a largo plazo (LTS) optimizadas para TPU. Los cambios en el SO que se indican en esta página solo se validan para las imágenes de Ubuntu LTS optimizadas para TPU y compatibles con Google.
- Eres responsable de extrapolar los cambios necesarios del SO para cualquier otra distribución del SO o imágenes personalizadas. Google no garantiza que las modificaciones para Ubuntu que se indican en esta página funcionen con otras distribuciones del SO o con otra imagen de Ubuntu con un kernel personalizado.
- Google no compila ni proporciona pruebas para ninguna imagen de SO que no sean las imágenes predeterminadas de Ubuntu LTS optimizadas para TPU. Debes compilar y probar tu imagen de SO personalizada.
Para obtener más información sobre las imágenes de Ubuntu LTS optimizadas para TPU predeterminadas, consulta Imágenes del SO de TPU.
Requisitos previos
Tu imagen base debe tener instalados los siguientes componentes:
- Python 3
- gcloud CLI
Realiza modificaciones durante la creación de imágenes
Aplica las siguientes modificaciones mientras compilas tu imagen personalizada de Ubuntu.
Vincula dispositivos de TPU a VFIO
Para permitir que el SO invitado acceda al hardware de la TPU, debes vincular los dispositivos de TPU al controlador vfio-pci.
Crea un archivo de reglas udev llamado
99-tpu-vfiopci.rulesen/etc/udev/rules.d/:# Rules for binding vfio-enabled TPU devices to vfio-pci. # v5p SUBSYSTEM=="pci", ACTION=="add", ATTRS{vendor}=="0x1ae0", ATTRS{device}=="0x0062", ATTRS{subsystem_vendor}=="0x1ae0", ATTRS{subsystem_device}=="0x00ad", DRIVER!="vfio-pci", TAG+="bind_to_vfio_pci" # v6e SUBSYSTEM=="pci", ACTION=="add", ATTRS{vendor}=="0x1ae0", ATTRS{device}=="0x006f", ATTRS{subsystem_vendor}=="0x1ae0", ATTRS{subsystem_device}=="0x00d1", DRIVER!="vfio-pci", TAG+="bind_to_vfio_pci" # TPU7x SUBSYSTEM=="pci", ACTION=="add", ATTRS{vendor}=="0x1ae0", ATTRS{device}=="0x0076", ATTRS{subsystem_vendor}=="0x1ae0", ATTRS{subsystem_device}=="0x00f2", DRIVER!="vfio-pci", TAG+="bind_to_vfio_pci" # Bind all 'bind_to_vfio_pci' tagged devices to vfio-pci. TAG=="bind_to_vfio_pci", RUN+="/lib/udev/bind_to_vfio_pci.sh $kernel"Crea una secuencia de comandos llamada
bind_to_vfio_pci.shen/lib/udev/:#!/bin/bash #!/usr/bin/env bash # Run ./bind_to_vfio_pci.sh <DBDF> # Binds the device at <DBDF> to vfio-pci. # If the device is already bound to a driver, unbinds it first. # Load the vfio-pci module into the kernel. No-op if already loaded. modprobe vfio-pci DBDF_REGEX="^[[:xdigit:]]{4}:[[:xdigit:]]{2}:[[:xdigit:]]{2}.[[:xdigit:]]$" unset BDF if [[ $1 =~ $DBDF_REGEX ]]; then BDF=$1 else echo "Error: BDF arg ($1) is not in form dddd:bb:dd.f" exit 1 fi PCI_PATH="/sys/bus/pci/devices/$BDF" echo "vfio-pci" > "$PCI_PATH/driver_override" PCI_DRIVER_PATH="$PCI_PATH/driver" if [[ -d "$PCI_DRIVER_PATH" ]]; then curr_driver=$(readlink "$PCI_DRIVER_PATH") curr_driver=${curr_driver##*/} if [[ $curr_driver == "vfio-pci" ]]; then echo "$BDF already bound to vfio-pci" exit 0 else echo "$BDF" > "$PCI_DRIVER_PATH/unbind" if [[ -d "$PCI_DRIVER_PATH" ]]; then echo "Error: Unable to unbind $PCI_DRIVER_PATH" exit 1 fi echo "Unbound $BDF from driver $curr_driver" fi fi echo "$BDF" > /sys/bus/pci/drivers_probe echo "Bound $BDF to vfio-pci" # Grant read/write access on VFIO device to all users IOMMU_GROUP=$(readlink "$PCI_PATH/iommu_group" | xargs basename) VFIO_DEV="/dev/vfio/$IOMMU_GROUP" if [[ -c "$VFIO_DEV" ]]; then chmod 0666 "$VFIO_DEV" else echo "$VFIO_DEV not found" exit 1 fi # Set allow_unsafe_interrupts for x86 platforms. (uname -a | grep -q x86_64) && echo 1 > /sys/module/vfio_iommu_type1/parameters/allow_unsafe_interrupts # This is only needed to avoid non-zero exit code from previous command. echo "All Done!"Haz que la secuencia de comandos sea ejecutable:
chmod +x /lib/udev/bind_to_vfio_pci.shOtorga a todos los usuarios del sistema acceso al dispositivo TPU:
echo 'KERNEL=="accel*" MODE="0666"' >> /etc/udev/rules.d/99-tpu.rules
Modifica la imagen para mejorar el rendimiento
Para garantizar un rendimiento óptimo, ajusta los siguientes límites y parámetros del sistema.
Límites de memoria
Para permitir que un solo proceso bloquee una cantidad ilimitada de memoria, actualiza /etc/security/limits.conf de la siguiente manera:
echo '* hard memlock unlimited' >> /etc/security/limits.conf
echo '* soft memlock unlimited' >> /etc/security/limits.conf
Límites de archivos
Actualiza /etc/security/limits.conf para aumentar la cantidad de archivos abiertos:
echo "* soft nofile 100000" >> /etc/security/limits.conf
echo "* hard nofile 100000" >> /etc/security/limits.conf
echo "root soft nofile 100000" >> /etc/security/limits.conf
echo "root hard nofile 100000" >> /etc/security/limits.conf
Parámetros del kernel
Actualiza la configuración de GRUB (por lo general, en /etc/default/grub) para incluir los siguientes parámetros en GRUB_CMDLINE_LINUX:
idle=poll: Evita que la CPU ingrese en estados de inactividad de bajo consumo.intel_iommu=on,sm_on: Habilita la unidad de administración de memoria de entrada/salida (IOMMU) de Intel. Se requiere para las arquitecturas de TPU7x y v5p.transparent_hugepage=always: Habilita las páginas enormes transparentes (THP).
En los siguientes pasos, se muestra cómo actualizar estos parámetros del kernel:
Para evitar que la CPU pase a un estado de inactividad de bajo consumo, configura la siguiente variable, que usarás en el siguiente paso.
kernel_cmdline="idle=poll"Habilita la unidad de administración de memoria de entrada y salida (IOMMU) de Intel. Este paso es obligatorio para TPU7x y TPU v5p.
kernel_cmdline="${kernel_cmdline} intel_iommu=on,sm_on"; sed -i "s/GRUB_CMDLINE_LINUX=\"\"/GRUB_CMDLINE_LINUX=\"${kernel_cmdline}\"/" /etc/default/grub echo "Status: New kernel cmdline: $(cat /etc/default/grub | grep -e '^GRUB_CMDLINE_LINUX=')" update-grubHabilita las páginas enormes transparentes (THP):
echo "Status: Enabling THP" sed -i -r 's/GRUB_CMDLINE_LINUX="[a-zA-Z0-9_= ]*/& transparent_hugepage=always/' /etc/default/grub update-grub
Instala el agente de vBar
El agente vBar es necesario para que funcione la red de interconexión entre chips (ICI).
Para instalar el agente de vBar, ejecuta los siguientes comandos:
Autentica Docker con Artifact Registry:
gcloud auth configure-docker us-docker.pkg.devExtrae la imagen de Docker de Artifact Registry:
docker pull gcr.io/cloud-tpu-v2-images/vbar_control_agent:0.0.1Ejecuta un contenedor con la imagen del agente vBar:
docker run --privileged --net=host vbar_control_agent:0.0.1
Opcional: Instala y ejecuta el recopilador de telemetría de IA
El recopilador de telemetría de IA se ejecuta dentro de la VM de TPU y te permite acceder a las métricas de infraestructura y de tiempo de ejecución a través de Cloud Monitoring o de tu propia canalización de supervisión basada en Prometheus. Puedes usar el recopilador de telemetría de IA con un SO personalizado a través de la imagen de Docker ai-telemetry-collector. Puedes instalar la imagen en tu SO personalizado y usar un archivo config.yaml para indicar los intervalos de recopilación, habilitar o inhabilitar métricas específicas, o cambiar los destinos de exportación.
Para instalar el recopilador de telemetría de IA, ejecuta los siguientes comandos:
Autentica Docker con Artifact Registry:
gcloud auth configure-docker us-docker.pkg.devExtrae la imagen de Docker de Artifact Registry:
docker pull gcr.io/cloud-tpu-v2-images/ai-telemetry-collector:latestEjecuta un contenedor con la imagen del recopilador de telemetría de IA con la configuración predeterminada:
docker run --privileged --net=host ai-telemetry-collector:latestPara obtener información sobre cómo usar un archivo de configuración personalizado o agregar archivos de configuración adicionales, consulta AI Telemetry Collector.
Realiza modificaciones en el tiempo de inicio
Configura tu imagen para que realice las tareas de las siguientes secciones cada vez que se inicie una VM. Puedes usar la herramienta cloud-init para configurar tareas de tiempo de arranque pasando metadatos a tus instancias. Las configuraciones de las siguientes secciones usan módulos como write_files y runcmd.
Los fragmentos que definen los archivos que se escribirán deben incluirse en la clave write_files:, y los comandos que se deben ejecutar durante el inicio deben incluirse en la clave runcmd: en tu configuración de cloud-init.
Inicia el agente de vBar
Inicia el agente de control de vBar con los IDs de usuario y grupo adecuados:
vbar_control_agent --logtostderr --gid= --uid= --chroot= --census_enabled=false --loas_pwd_fallback_in_corp
Configure las variables de entorno
Para asegurarte de que tu entorno se inicialice correctamente para las cargas de trabajo de TPU, debes recuperar las variables de configuración del tiempo de ejecución del servidor de metadatos de Compute Engine durante el proceso de inicio del sistema. Para ello, agrega el siguiente fragmento a la sección write_files: de tu configuración de cloud-init, lo que crea un script llamado /var/scripts/configure-env-vars.sh. Esta secuencia de comandos automatiza la recuperación de atributos de la clave de metadatos tpu-env y los guarda en /${HOME}/tpu-env para que los use la pila de software de la TPU.
- path: /var/scripts/configure-env-vars.sh
permissions: 0444
owner: root
content: |
grep -q CLOUDSDK_PYTHON /etc/environment || echo "CLOUDSDK_PYTHON=/usr/bin/python3" >> /etc/environment
export HOME=/home/tpu-runtime
curl -s 'http://metadata.google.internal/computeMetadata/v1/instance/attributes/tpu-env' -H 'Metadata-Flavor: Google' > /tmp/tpu-env.yaml
eval $(python3 -c '''
import yaml
stream_in=open("/tmp/tpu-env.yaml", "r")
for k,v in yaml.safe_load(stream_in).items():
print("{var}=\"{value}\"".format(var = k, value = str(v)))
''' > "/${HOME}/tpu-env"
)
rm -f "/tmp/tpu-env.yaml"
printenv
cat ${HOME}/tpu-env
Obtén metadatos de la VM
El siguiente fragmento crea una secuencia de comandos llamada /var/scripts/get-vm-metadata.py, una utilidad de Python para consultar de forma programática el servidor de metadatos en busca de atributos de instancia específicos y etiquetas de metadatos personalizadas. Agrega lo siguiente a la sección write_files: de tu configuración de cloud-init:
- path: /var/scripts/get-vm-metadata.py
permissions: 0444
owner: root
content: |
import sys, requests, os
if len(sys.argv) < 2:
sys.stderr.write('Must provide key')
os._exit(1)
key = sys.argv[1]
default = None
if len(sys.argv) > 2:
default = sys.argv[2]
attribute_type = 'attributes'
if len(sys.argv) > 3:
attribute_type = sys.argv[3]
request = requests.get("http://metadata.google.internal/computeMetadata/v1/instance/{}/{}".format(attribute_type, key), headers={'Metadata-Flavor': 'Google'})
if request.status_code == 200:
print(request.content)
elif request.status_code == 404 or request.status_code == '403':
sys.stderr.write('Metadata key: {} does not exist\n'.format(key))
if default:
print(default)
else:
sys.stderr.write('Lookup failed with: {}'.format(request))
Aumenta los tiempos de espera de Cloud Storage
Si tu carga de trabajo interactúa con Cloud Storage, aumenta la duración del tiempo de espera agregando valores de tiempo de espera a /etc/environment. Para ello, agrega el siguiente fragmento a la sección write_files: de tu configuración de cloud-init, que crea una secuencia de comandos llamada /var/scripts/configure-gcs-timeouts.sh.
- path: /var/scripts/configure-gcs-timeouts.sh
permissions: 0444
owner: root
content: |
echo "GCS_RESOLVE_REFRESH_SECS=60" >> /etc/environment
echo "GCS_REQUEST_CONNECTION_TIMEOUT_SECS=300" >> /etc/environment
echo "GCS_METADATA_REQUEST_TIMEOUT_SECS=300" >> /etc/environment
echo "GCS_READ_REQUEST_TIMEOUT_SECS=300" >> /etc/environment
echo "GCS_WRITE_REQUEST_TIMEOUT_SECS=600" >> /etc/environment
¿Qué sigue?
- Revisa las imágenes del SO de TPU disponibles.
- Obtén más información para administrar VMs de TPU.