OpenXLA یک کامپایلر مخصوص دامنه برای جبر خطی است که میتواند مدلهای TensorFlow را بدون تغییر کد منبع تسریع کند.
هنگامی که یک برنامه TensorFlow اجرا می شود، تمام عملیات ها به صورت جداگانه توسط مجری TensorFlow اجرا می شوند. هر عملیات TensorFlow دارای یک هسته GPU از پیش کامپایل شده است که مجری آن را به آن ارسال می کند.
XLA یک حالت جایگزین برای اجرای مدلها ارائه میکند: گراف TensorFlow را به دنبالهای از هستههای محاسباتی که بهطور خاص برای مدل دادهشده تولید شدهاند، کامپایل میکند. از آنجایی که این هسته ها منحصر به مدل هستند، می توانند از اطلاعات خاص مدل برای بهینه سازی بهره برداری کنند. به عنوان مثال، اجازه دهید به بهینه سازی XLA در زمینه یک محاسبه ساده TensorFlow نگاه کنیم:
def model_fn(x, y, z):
return tf.reduce_sum(x + y * z)
بدون XLA اجرا شود، گراف سه هسته را راه اندازی می کند: یکی برای ضرب، یکی برای جمع و دیگری برای کاهش. با این حال، XLA میتواند نمودار را طوری بهینه کند که نتیجه را در یک کرنل محاسبه کند. این کار را با "ادغام" جمع، ضرب و کاهش در یک هسته GPU انجام می دهد. علاوه بر این، این عملیات ذوب شده مقادیر میانی تولید شده توسط y*z
و x+y*z
در حافظه نمینویسد. در عوض نتایج این محاسبات میانی را مستقیماً به کاربران خود ارسال می کند و در عین حال آنها را کاملاً در رجیسترهای GPU نگه می دارد. Fusion مهمترین بهینه سازی XLA است. پهنای باند حافظه معمولاً کمیاب ترین منبع در شتاب دهنده های سخت افزاری است، بنابراین حذف عملیات حافظه یکی از بهترین راه ها برای بهبود عملکرد است.
tf.function(jit_compile=True)
API کامپایل صریح یک کنترل دقیق برای انتخاب توابع کامپایل ارائه می دهد. به عنوان مثال، تابع TensorFlow زیر که آموزش MNIST را انجام می دهد با XLA کامپایل شده است:
@tf.function(jit_compile=True)
def train_mnist(images, labels):
images, labels = cast(images, labels)
with tf.GradientTape() as tape:
predicted_labels = layer(images)
loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
logits=predicted_labels, labels=labels
))
layer_variables = layer.trainable_variables
grads = tape.gradient(loss, layer_variables)
optimizer.apply_gradients(zip(grads, layer_variables))
API jit_compile
دارای معنایی باید کامپایل باشد : یا کل تابع با XLA کامپایل شده است یا یک errors.InvalidArgumentError
استثنا پرتاب می شود. XLA در حال حاضر نمی تواند توابعی را در جایی که ابعاد قابل استنباط نیست کامپایل کند: یعنی اگر امکان استنتاج ابعاد همه تانسورها بدون اجرای کل محاسبات وجود نداشته باشد. به عنوان مثال، تابع زیر کامپایل نمی شود:
@tf.function
def not_compilable(x):
return tf.unique(x)
شکل ها می توانند در طول اجراها متفاوت باشند:
@tf.function(jit_compile=True)
def recompiled_on_launch(a, b):
return a + b
recompiled_on_launch(tf.ones([1, 10]), tf.ones([1, 10]))
recompiled_on_launch(tf.ones([1, 100]), tf.ones([1, 100]))
برای مثال استفاده دقیق تر، و یک ویدیوی آموزشی در مورد jit_compile=True
به colab آموزشی مراجعه کنید.
برای مدلهای Keras، jit_compile=True
را میتوان به عنوان آرگومان برای model.compile
تنظیم کرد:
model.compile(optimizer="adam", jit_compile=True)
XLA:GPU را می توان با استراتژی توزیع شده TF ( MirroredStrategy
یا MultiWorkerMirroredStrategy
) با حاشیه نویسی تابع step با jit_compile=True
استفاده کرد:
@tf.function(jit_compile=True)
def step_fn():
t = tf.ones(shape=[100], dtype=tf.float32)
ctx = tf.distribute.get_replica_context()
return ctx.all_reduce(tf.distribute.ReduceOp.SUM, t)
@tf.function
def run_fn():
return strategy.run(step_fn)
یک راه ساده برای شروع استفاده از XLA در مدلهای TensorFlow بدون هیچ تغییری، فعال کردن خوشهبندی خودکار است که بهطور خودکار خوشهها (زیرگرافهای متصل) را در توابع TensorFlow پیدا میکند که میتوانند با استفاده از XLA کامپایل و اجرا شوند. با تنظیم متغیر محیطی TF_XLA_FLAGS
می توان خوشه بندی خودکار در GPU را فعال کرد:
$ TF_XLA_FLAGS=--tf_xla_auto_jit=2 path/to/your/tf/program
خوشه بندی خودکار در حال حاضر برای بارهای کاری GPU بهینه شده است، اما همچنین می توان آن را با استفاده از پرچم --tf_xla_cpu_global_jit
در CPU نیز فعال کرد:
$ TF_XLA_FLAGS="--tf_xla_auto_jit=2 --tf_xla_cpu_global_jit" path/to/your/program
برای مثال استفاده دقیق به مجموعه آموزشی خوشه بندی خودکار مراجعه کنید.
tfcompile
شما همچنین می توانید از یک ابزار tfcompile
مستقل استفاده کنید که نمودار TensorFlow را به کد اجرایی تبدیل می کند (فقط برای x86-64 CPU).
XLA امکانات درون نگری را فراهم می کند که به شما امکان می دهد برنامه های تولید شده را بررسی کنید. برای تخلیه برنامه های تولید شده، از متغیر محیطی XLA_FLAGS
استفاده کنید:
$ XLA_FLAGS="--xla_dump_to=/tmp/generated" TF_XLA_FLAGS="--tf_xla_auto_jit=2" my/tensorflow/program
پس از انجام تخلیه، می توانید فایل های زیر را در /tmp/generated
پیدا کنید:
module_XXXX.*_optimizations.txt
برنامه های XLA را تولید کرد، یکی در هر خوشه کامپایل شده. پیوست کردن آنها هنگام ارسال گزارشهای باگ XLA بسیار مفید است!module_XXXX.ir-*.ll
فایل های تولید شده در نمایش متوسط LLVM ، با NVPTX درونی.module_XXXX.ptx
فایل های PTX تولید شده است.
همچنین می توانید نمودار را با تجسم جاسازی خوشه های XLA در داخل گراف TensorFlow با استفاده از:
$ TF_DUMP_GRAPH_PREFIX=/tmp/generated TF_XLA_FLAGS="--tf_xla_clustering_debug"
بازتولید گزارش باگ بسیار آسانتر است اگر شامل موارد خالی برای برنامههای XLA تولید شده و تعبیه خوشهبندی خودکار مورد استفاده باشد. برای تولید آنها برای یک برنامه TensorFlow که با خوشه بندی خودکار اجرا می شود، راه اندازی کنید:
$ TF_DUMP_GRAPH_PREFIX=/tmp/generated \
TF_XLA_FLAGS="--tf_xla_clustering_debug --tf_xla_auto_jit=2" \
XLA_FLAGS="--xla_dump_hlo_as_text --xla_dump_to=/tmp/generated" \
my/tensorflow/program"
هنگام ثبت اشکالات، محتویات دایرکتوری /tmp/generated
(که در بالا به آن اشاره شد) را پیوست کنید.
در صورت امکان، با استفاده از run_hlo_module
و اجرای مکرر آن بر روی برنامه های تولید شده، سعی کنید باگ را در یک برنامه XLA جدا کنید.
- اسناد OpenXLA اسناد OpenXLA
- مشکلات شناخته شده فهرست مشکلات شناخته شده با XLA+TF
- XLA - TensorFlow، گردآوری شده : در وبلاگ توسعه دهندگان Google بخوانید
- منبع XLA را در Github بررسی کنید!
به غیر از TensorFlow، برنامه های XLA را می توان با موارد زیر تولید کرد:
- JAX : تبدیلهای قابل ترکیب برنامههای Python+NumPy
- جولیا : زبان جولیا برای محاسبات علمی
- PyTorch : چارچوب PyTorch
- Nx : کتابخانه محاسبات عددی برای زبان برنامه نویسی Elixir
jit_compile=True