Ваше универсальное руководство по всем изменениям в продвижении типа в Tensorflow 2.15

Ваше универсальное руководство по всем изменениям в продвижении типа в Tensorflow 2.15

21 июля 2025 г.

Обзор контента

  • Обзор
  • Настраивать
  • Включение нового типа продвижения
  • Два режима: все режим против безопасного режима
  • Dtypes
  • Пример точных проигрышных операций
  • Пример операций по выбору битов
  • Система, основанная на решетке
  • Тип продвижения решетки
  • Таблица продвижения типа
  • Преимущества нового типа продвижения
  • Слабак
  • Обзор
  • Слабая строительство

Обзор

В TensorFlow есть 4 варианта продвижения типа.

  • По умолчанию TensorFlow повышает ошибки вместо того, чтобы продвигать типы для операций смешанного типа.
  • Бегtf.numpy.experimental_enable_numpy_behavior()переключает TensorFlow для использованияПравила продвижения типа NumpyАнкет
  • Этот докописывает два новых варианта, которые будут доступны в TensorFlow 2.15 (или в настоящее время вtf-nightly):

pip install -q tf_nightly

Примечание:experimental_enable_numpy_behaviorменяет поведение всего тензора.

Настраивать

import numpy as np
import tensorflow as tf
import tensorflow.experimental.numpy as tnp

print("Using TensorFlow version %s" % tf.__version__)

Using TensorFlow version 2.20.0-dev20250306

Включение нового типа продвижения

Чтобы использоватьJax-подобный тип продвиженияВ TF-Numpy укажите либо'all'или'safe'в качестве режима преобразования dtype при включении поведения Numpy для Tensorflow.

Эта новая система (сdtype_conversion_mode="all") ассоциируется, коммутативен и позволяет легко контролировать, какая ширина плавания вы в конечном итоге (он не автоматически конвертируется в более широкие поплавки). Это вносит некоторые риски переполнения и потери точности, ноdtype_conversion_mode="safe"заставляет вас явно рассмотреть эти случаи. Два режима объяснены более подробно вСледующий разделАнкет

tnp.experimental_enable_numpy_behavior(dtype_conversion_mode="all")

WARNING:tensorflow:UserWarning: enabling the new type promotion must happen at the beginning of the program. Please ensure no TF APIs have been used yet.

Два режима: все режим против безопасного режима

В системе продвижения нового типа мы вводим два режима:ALLрежим иSAFEрежим.SAFEРежим используется для смягчения проблем «рискованных» рекламных акций, которые могут привести к потере точности или излучению битов.

Dtypes

Мы будем использовать следующие сокращения для краткости.

  • bозначаетtf.bool
  • u8означаетtf.uint8
  • i16означаетtf.int16
  • i32означаетtf.int32
  • bf16означаетtf.bfloat16
  • f32означаетtf.float32
  • f64означаетtf.float64
  • i32*означает PythonintИли слабоi32
  • f32*означает PythonfloatИли слабоf32
  • c128*означает PythoncomplexИли слабоc128

Звездочка (*) обозначает, что соответствующий тип является «слабым» - такой DTYPE временно выводится системой и может отложить другие DTYPE. Эта концепция объяснена более подробноздесьАнкет

Пример точных проигрышных операций

В следующем примере,i32 + f32допускается вALLрежим, но не вSAFEРежим из -за риска потери точности.

# i32 + f32 returns a f32 result in ALL mode.
tnp.experimental_enable_numpy_behavior(dtype_conversion_mode="all")
a = tf.constant(10, dtype = tf.int32)
b = tf.constant(5.0, dtype = tf.float32)
a + b  # <tf.Tensor: shape=(), dtype=float32, numpy=15.0>

WARNING:tensorflow:UserWarning: enabling the new type promotion must happen at the beginning of the program. Please ensure no TF APIs have been used yet.
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1741314679.354086   16587 gpu_device.cc:2018] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 13638 MB memory:  -> device: 0, name: Tesla T4, pci bus id: 0000:00:05.0, compute capability: 7.5
I0000 00:00:1741314679.356319   16587 gpu_device.cc:2018] Created device /job:localhost/replica:0/task:0/device:GPU:1 with 13756 MB memory:  -> device: 1, name: Tesla T4, pci bus id: 0000:00:06.0, compute capability: 7.5
I0000 00:00:1741314679.358627   16587 gpu_device.cc:2018] Created device /job:localhost/replica:0/task:0/device:GPU:2 with 13756 MB memory:  -> device: 2, name: Tesla T4, pci bus id: 0000:00:07.0, compute capability: 7.5
I0000 00:00:1741314679.360752   16587 gpu_device.cc:2018] Created device /job:localhost/replica:0/task:0/device:GPU:3 with 13756 MB memory:  -> device: 3, name: Tesla T4, pci bus id: 0000:00:08.0, compute capability: 7.5
<tf.Tensor: shape=(), dtype=float32, numpy=15.0>

# This promotion is not allowed in SAFE mode.
tnp.experimental_enable_numpy_behavior(dtype_conversion_mode="safe")
a = tf.constant(10, dtype = tf.int32)
b = tf.constant(5.0, dtype = tf.float32)
try:
  a + b
except TypeError as e:
   print(f'{type(e)}: {e}')  # TypeError: explicitly specify the dtype or switch to ALL mode.

WARNING:tensorflow:UserWarning: enabling the new type promotion must happen at the beginning of the program. Please ensure no TF APIs have been used yet.
<class 'TypeError'>: In promotion mode PromoMode.SAFE, implicit dtype promotion between (<dtype: 'int32'>, weak=False) and (<dtype: 'float32'>, weak=False) is disallowed. You need to explicitly specify the dtype in your op, or relax your dtype promotion rules (such as from SAFE mode to ALL mode).

Пример операций по выбору битов

В следующем примере,i8 + u32допускается вALLрежим, но не вSAFEРежим из-за вычисления битов, что означает использование большего количества бит, чем количество бит в входах. Обратите внимание, что новая семантика продвижения в новом типе позволяет только необходимое излучение битов.

# i8 + u32 returns an i64 result in ALL mode.
tnp.experimental_enable_numpy_behavior(dtype_conversion_mode="all")
a = tf.constant(10, dtype = tf.int8)
b = tf.constant(5, dtype = tf.uint32)
a + b

WARNING:tensorflow:UserWarning: enabling the new type promotion must happen at the beginning of the program. Please ensure no TF APIs have been used yet.
<tf.Tensor: shape=(), dtype=int64, numpy=15>

# This promotion is not allowed in SAFE mode.
tnp.experimental_enable_numpy_behavior(dtype_conversion_mode="safe")
a = tf.constant(10, dtype = tf.int8)
b = tf.constant(5, dtype = tf.uint32)
try:
  a + b
except TypeError as e:
   print(f'{type(e)}: {e}')  # TypeError: explicitly specify the dtype or switch to ALL mode.

WARNING:tensorflow:UserWarning: enabling the new type promotion must happen at the beginning of the program. Please ensure no TF APIs have been used yet.
<class 'TypeError'>: In promotion mode PromoMode.SAFE, implicit dtype promotion between (<dtype: 'int8'>, weak=False) and (<dtype: 'uint32'>, weak=False) is disallowed. You need to explicitly specify the dtype in your op, or relax your dtype promotion rules (such as from SAFE mode to ALL mode).

Система, основанная на решетке

Тип продвижения решетки

Новое поведение по продвижению типа определяется с помощью решетки по продвижению следующего типа:

В частности, продвижение между любыми двумя типами определяется путем поиска первого распространенного ребенка двух узлов (включая сами узлы).

Например, на приведенной выше диаграмме первого распространенного ребенкаi8иi32являетсяi32Потому что два узла впервые пересекаютсяi32при следующем направлении стрел.

Точно так же как другой пример, тип продвижения результатов междуu64иf16будетf16Анкет

Таблица продвижения типа

Следующая решетка генерирует бинарную таблицу продвижения ниже:

Примечание:SAFEРежим рассеивает выделенные ячейки.ALLРежим допускает все случаи.

Преимущества нового типа продвижения

Мы принимаем систему на основе решетки, подобную JAX, для нашего нового типа продвижения, которая предлагает следующие преимущества:

Преимущества системы на основе решетки

Во-первых, использование системы на основе решетки обеспечивает три очень важных свойств:

  • Существование: существует уникальный тип продвижения результатов для любых комбинаций типов.
  • Коммутативность:a + b = b + a
  • Ассоциативность:a + (b + c) = (a + b) = c

Эти три свойства имеют решающее значение для создания семантики продвижения типа, которая является последовательной и предсказуемой.

Преимущества jax-подобной решеткой системы

Еще одним важным преимуществом системы, похожей на JAX, является то, что внешние неподтвержденные INT, она позволяет избежать всех более широких акций. Это означает, что вы не можете получить 64-битные результаты без 64-битных входов. Это особенно полезно для работы над акселераторами, поскольку это позволяет избежать ненужных 64-разрядных значений, которые часто встречались при продвижении старого типа.

Тем не менее, это идет с компромиссом: смешанная реклама Float/Integer очень подвержено точной потере. Например, в примере ниже,i64 + f16приводит к продвижениюi64кf16Анкет

# The first input is promoted to f16 in ALL mode.
tnp.experimental_enable_numpy_behavior(dtype_conversion_mode="all")
tf.constant(1, tf.int64) + tf.constant(3.2, tf.float16)  # <tf.Tensor: shape=(), dtype=float16, numpy=4.2>

WARNING:tensorflow:UserWarning: enabling the new type promotion must happen at the beginning of the program. Please ensure no TF APIs have been used yet.
<tf.Tensor: shape=(), dtype=float16, numpy=4.19921875>

Чтобы связать эту проблему, мы представилиSAFEРежим, который запретит эти «рискованные» акции.

Примечание:Чтобы узнать больше о соображениях дизайна при построении решетки, пожалуйста, обратитесь кДизайн семантики продвижения типа для JAXАнкет

Слабак

Обзор

Слабые тензорыТенсоры, которые "слабо набирают", похожие наКонцепция в JAXАнкет

WeakTensorDtype временно выведен системой и может отложить другие dtypes. Эта концепция вводится в новом акции типа, чтобы предотвратить нежелательное продвижение типа в рамках бинарных операций между значениями TF и значениями без явного определенного пользователя типа, такого как скалярные литералы Python.

Например, в примере ниже,tf.constant(1.2)считается «слабым», потому что у него нет определенного DTYPE. Поэтому,tf.constant(1.2)Отвечает на тип типаtf.constant(3.1, tf.float16), в результате чегоf16выход.

tf.constant(1.2) + tf.constant(3.1, tf.float16)  # <tf.Tensor: shape=(), dtype=float16, numpy=4.3>

<tf.Tensor: shape=(), dtype=float16, numpy=4.30078125>

Слабая строительство

О слабыхпенсорах создаются, если вы создаете тензор без указания DTYPE, результатом является слабак. Вы можете проверить, является ли тензор «слабым» или нет, проверив слабый атрибут в конце представления строкости тензора.

Первый случай: Когдаtf.constantвызывается с вводом без определенного пользователя dtype.

tf.constant(5)  # <tf.Tensor: shape=(), dtype=int32, numpy=5, weak=True>

<tf.Tensor: shape=(), dtype=int32, numpy=5, weak=True>

tf.constant([5.0, 10.0, 3])  # <tf.Tensor: shape=(3,), dtype=float32, numpy=array([ 5., 10.,  3.], dtype=float32), weak=True>

<tf.Tensor: shape=(3,), dtype=float32, numpy=array([ 5., 10.,  3.], dtype=float32), weak=True>

# A normal Tensor is created when dtype arg is specified.
tf.constant(5, tf.int32)  # <tf.Tensor: shape=(), dtype=int32, numpy=5>

<tf.Tensor: shape=(), dtype=int32, numpy=5>

Второй случай: Когда ввод без определенного пользователя DTYPE передается вОслабленная поддержка APIАнкет

tf.math.abs([100.0, 4.0])  # <tf.Tensor: shape=(2,), dtype=float32, numpy=array([100., 4.], dtype=float32), weak=True>

<tf.Tensor: shape=(2,), dtype=float32, numpy=array([100.,   4.], dtype=float32), weak=True>

Первоначально опубликовано наTensorflowВеб -сайт, эта статья появляется здесь под новым заголовком и имеет лицензию в CC на 4.0. Образцы кода, разделенные по лицензии Apache 2.0.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE