Menggunakan image OS kustom

Anda dapat menggunakan image OS kustom untuk VM TPU guna memuat software sebelumnya, menggunakan distribusi OS tertentu, atau menerapkan modifikasi kernel kustom. Membuat image kustom melibatkan pembuatan modifikasi sistem tertentu selama proses pembuatan image dan mengonfigurasi image untuk menangani tugas waktu booting yang diperlukan untuk fungsi TPU.

Perhatikan pernyataan penyangkalan berikut jika Anda menggunakan image OS kustom dengan TPU:

  • Google menyediakan image dukungan jangka panjang (LTS) Ubuntu yang dioptimalkan untuk TPU secara default. Perubahan OS yang tercantum di halaman ini hanya divalidasi untuk image Ubuntu LTS yang dioptimalkan untuk TPU dan didukung Google.
  • Anda bertanggung jawab untuk mengekstrapolasi perubahan OS yang diperlukan untuk distribusi OS atau image kustom lainnya. Google tidak menjamin bahwa modifikasi untuk Ubuntu yang tercantum di halaman ini akan berfungsi dengan distribusi OS lain atau image Ubuntu lain dengan kernel kustom.
  • Google tidak membuat atau menyediakan pengujian untuk image OS selain image Ubuntu LTS yang dioptimalkan untuk TPU secara default. Anda harus membuat dan menguji image OS kustom.

Untuk mengetahui informasi selengkapnya tentang image Ubuntu LTS yang dioptimalkan untuk TPU secara default, lihat Image OS TPU.

Prasyarat

Image dasar Anda harus menginstal komponen berikut:

  • Python 3
  • gcloud CLI

Melakukan perubahan selama pembuatan gambar

Terapkan modifikasi berikut saat membuat image Ubuntu kustom.

Mengikat perangkat TPU ke VFIO

Untuk mengizinkan OS tamu mengakses hardware TPU, Anda harus mengikat perangkat TPU ke driver vfio-pci.

  1. Buat file aturan udev bernama 99-tpu-vfiopci.rules di /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"
    
  2. Buat skrip bernama bind_to_vfio_pci.sh di /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!"
    
  3. Setel agar skrip dapat dieksekusi:

    chmod +x /lib/udev/bind_to_vfio_pci.sh
    
  4. Memberi semua pengguna di sistem akses ke perangkat TPU:

    echo 'KERNEL=="accel*" MODE="0666"' >> /etc/udev/rules.d/99-tpu.rules
    

Ubah gambar untuk meningkatkan performa

Untuk memastikan performa yang optimal, sesuaikan parameter dan batas sistem berikut.

Batas memori

Izinkan satu proses mengunci memori tanpa batas dengan memperbarui /etc/security/limits.conf:

echo '*  hard  memlock  unlimited' >> /etc/security/limits.conf
echo '*  soft  memlock  unlimited' >> /etc/security/limits.conf

Batas file

Tingkatkan jumlah file terbuka dengan memperbarui /etc/security/limits.conf:

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

Parameter kernel

Perbarui konfigurasi GRUB Anda (biasanya di /etc/default/grub) untuk menyertakan parameter berikut di GRUB_CMDLINE_LINUX:

  • idle=poll: Mencegah CPU memasuki status diam daya rendah.
  • intel_iommu=on,sm_on: Mengaktifkan Unit Pengelolaan Memori Input/Output (IOMMU) Intel. Diperlukan untuk arsitektur TPU7x dan v5p.
  • transparent_hugepage=always: Mengaktifkan Transparent Huge Pages (THP).

Langkah-langkah berikut menunjukkan cara memperbarui parameter kernel ini:

  1. Cegah CPU beralih ke status idle daya rendah dengan menyetel variabel berikut, yang akan Anda gunakan pada langkah berikutnya.

    kernel_cmdline="idle=poll"
    
  2. Aktifkan Intel Input-Output Memory Management Unit (IOMMU). Langkah ini diperlukan untuk TPU7x dan 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-grub
    
  3. Aktifkan Transparent Huge Pages (THP):

    echo "Status: Enabling THP"
    sed -i -r 's/GRUB_CMDLINE_LINUX="[a-zA-Z0-9_= ]*/& transparent_hugepage=always/' /etc/default/grub
    
    update-grub
    

Menginstal agen vBar

Agen vBar diperlukan agar jaringan interkoneksi antar-chip (ICI) dapat berfungsi.

Untuk menginstal agen vBar, jalankan perintah berikut:

  1. Mengautentikasi Docker dengan Artifact Registry:

    gcloud auth configure-docker us-docker.pkg.dev
    
  2. Tarik image Docker dari Artifact Registry:

    docker pull gcr.io/cloud-tpu-v2-images/vbar_control_agent:0.0.1
    
  3. Jalankan container menggunakan image agen vBar:

    docker run --privileged --net=host vbar_control_agent:0.0.1
    

Opsional: Menginstal dan menjalankan Pengumpul Telemetri AI

Pengumpul Telemetri AI berjalan di dalam VM TPU dan memungkinkan Anda mengakses metrik runtime dan infrastruktur melalui Cloud Monitoring atau melalui pipeline pemantauan berbasis Prometheus Anda sendiri. Anda dapat menggunakan Pengumpul Telemetri AI dengan OS kustom menggunakan image Docker ai-telemetry-collector. Anda dapat menginstal image ke OS kustom dan menggunakan file config.yaml untuk menentukan interval pengumpulan, mengaktifkan atau menonaktifkan metrik tertentu, atau mengubah tujuan ekspor.

Untuk menginstal AI Telemetry Collector, jalankan perintah berikut:

  1. Mengautentikasi Docker dengan Artifact Registry:

    gcloud auth configure-docker us-docker.pkg.dev
    
  2. Tarik image Docker dari Artifact Registry:

    docker pull gcr.io/cloud-tpu-v2-images/ai-telemetry-collector:latest
    
  3. Jalankan container menggunakan image AI Telemetry Collector dengan konfigurasi default:

    docker run --privileged --net=host ai-telemetry-collector:latest
    

    Untuk mengetahui informasi tentang cara menggunakan file konfigurasi kustom atau menambahkan file konfigurasi tambahan, lihat Pengumpul Telemetri AI.

Membuat modifikasi waktu booting

Konfigurasi image Anda untuk melakukan tugas di bagian berikut setiap kali VM di-boot. Anda dapat menggunakan alat cloud-init untuk mengonfigurasi tugas waktu booting dengan meneruskan metadata ke instance Anda. Konfigurasi di bagian berikut menggunakan modul seperti write_files dan runcmd. Cuplikan yang menentukan file yang akan ditulis harus disertakan di bawah kunci write_files:, dan perintah yang harus dijalankan saat waktu booting harus disertakan di bawah kunci runcmd: dalam konfigurasi cloud-init Anda.

Mulai agen vBar

Mulai agen kontrol vBar dengan ID pengguna dan grup yang sesuai:

vbar_control_agent --logtostderr --gid= --uid=  --chroot= --census_enabled=false --loas_pwd_fallback_in_corp

Mengonfigurasi variabel lingkungan

Untuk memastikan lingkungan Anda diinisialisasi dengan benar untuk workload TPU, Anda harus mengambil variabel konfigurasi runtime dari server metadata Compute Engine selama proses booting sistem. Untuk melakukannya, tambahkan cuplikan berikut ke bagian write_files: dari konfigurasi cloud-init Anda, yang akan membuat skrip bernama /var/scripts/configure-env-vars.sh. Skrip ini mengotomatiskan pengambilan atribut dari kunci metadata tpu-env dan menyimpannya di /${HOME}/tpu-env untuk digunakan oleh stack software 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

Mendapatkan metadata VM

Cuplikan berikut membuat skrip bernama /var/scripts/get-vm-metadata.py, utilitas Python untuk mengkueri server metadata secara terprogram untuk atribut instance tertentu dan tag metadata kustom. Tambahkan kode berikut ke bagian write_files: pada konfigurasi cloud-init Anda:

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

Meningkatkan waktu tunggu Cloud Storage

Jika workload Anda berinteraksi dengan Cloud Storage, tingkatkan durasi waktu tunggu dengan menambahkan nilai waktu tunggu ke /etc/environment. Untuk melakukannya, tambahkan cuplikan berikut ke bagian write_files: pada konfigurasi cloud-init Anda, yang membuat skrip bernama /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

Langkah berikutnya