تدوین XLA:GPU از قبل (AOT)

کامپایل پیش از زمان (AOT) یک محاسبه XLA را در یک محیط کامپایل و سریالایز می‌کند و به مصنوع دودویی حاصل اجازه می‌دهد تا بعداً توسط یک زمان اجرای جداگانه بارگذاری و اجرا شود.

برخلاف کامپایل درجا (JIT) که محاسبات را در فرآیند اجرا، پس از اولین اجرا کامپایل می‌کند، AOT کامپایل را از مسیر سرویس‌دهی حذف می‌کند که این امر تأخیر راه‌اندازی را کاهش می‌دهد و اجازه می‌دهد کامپایل در یک محیط ساخت اختصاصی اجرا شود.

گردش کار و APIها

خط لوله استاندارد AOT شامل مراحل کامپایل، سریال‌سازی و بارگذاری/غیرسریال‌سازی است:

  • نقاط ورود PjRt: در رابط C++ PjRt ( xla/pjrt/pjrt_client.h )، کامپایل از طریق PjRtClient::Compile (یا CompileAndLoad ) آغاز می‌شود. فایل اجرایی حاصل از طریق PjRtExecutable::SerializeExecutable به یک رشته سریالی می‌شود. در میزبان سرویس‌دهنده، زمان اجرا فایل اجرایی را با استفاده از PjRtClient::DeserializeExecutable بازسازی می‌کند یا آن را مستقیماً برای اجرا با PjRtClient::LoadSerializedExecutable بارگذاری می‌کند.
  • مصنوعات سطح کامپایلر: در لایه کامپایلر، کامپایل پیش از زمان، یک GpuAotCompilationResult (یک CompiledModule ؛ AotCompilationResult یک نام مستعار منسوخ شده است) تولید می‌کند. این شیء، GpuExecutableProto سریالی شده را کپسوله‌سازی کرده و SerializeAsString() و LoadExecutable() را در معرض نمایش قرار می‌دهد.
  • ابزار خط فرمان: ابزار xla_compile ماژول‌های HLO یا StableHLO را به فایل‌های اجرایی سریالی کامپایل می‌کند:

    xla_compile --module_file=module.hlo --output_file=output.bin \
        --platform=gpu --gpu_target_config=gpu_target_config.pbtxt
    

    کامپایل می‌تواند با ارائه پیکربندی دستگاه هدف، روی یک میزبان بدون پردازنده گرافیکی (GPU) اجرا شود ( به فایل راهنمای کاربر xla/backends/gpu/target_config مراجعه کنید).

سریال سازی چیست؟

کانتینر سطح بالا برای برنامه‌های GPU سریالی شده GpuExecutableProto است:

  • thunks : توالی اجرای thunks. thunks هسته (برای مثال CustomKernelThunk ) فایل‌های باینری هسته کامپایل شده خود را جاسازی می‌کنند ( cubin برای NVIDIA، hsaco برای ROCm)، بنابراین بیشتر کد دستگاه در اینجا قرار دارد.
  • binary : یک فایل باینری دستگاه در سطح ماژول. امروزه فقط بافرهای ثابت ماژول را حمل می‌کند؛ هسته‌ها دیگر در اینجا ذخیره نمی‌شوند.
  • buffer_allocations : اندازه‌های بافر و برش‌های تخصیص.
  • gpu_compute_capability : قابلیت معماری سخت‌افزاری کامپایل تارگت.
  • executable_abi_version : نسخه‌های زنجیره ابزار و ABI زمان اجرا.
  • hlo_module_with_config : متادیتای سریال‌سازی‌شده‌ی HloModuleProto و دیباگ در آن تعبیه شده است.

هر پیام و فیلد پروتو که به صورت گذرا از GpuExecutableProto قابل دسترسی است، بخشی از قرارداد سازگاری است که در راهنمای سازگاری GPU AOT شرح داده شده است.

چگونه یک مصنوع بارگذاری و اجرا می‌شود

  1. بازسازی گراف thunk: ورودی‌های ThunkProto را در توالی thunk درون حافظه deserialize کنید و نمادهای فراخوانی سفارشی، FFI و هسته را در طول مسیر حل کنید. ماژول HLO تعبیه شده نیز تجزیه می‌شود، بنابراین یک کد عملیاتی HLO که برای فایل باینری در حال بارگذاری ناشناخته است، بارگذاری را با شکست مواجه می‌کند.
  2. اجرای مراحل تبدیل گراف thunk: بهینه‌سازی زمان بارگذاری و مراحل تبدیل را روی thunkهای درون حافظه اجرا کنید (برای مثال، ساخت CommandBufferThunk های زمان اجرا برای ارسال کار از طریق گراف‌های CUDA). CommandBufferThunk به صورت پویا در زمان بارگذاری بازسازی می‌شود و هرگز مستقیماً سریالی نمی‌شود.
  3. تخصیص بافرها: فضاهای حافظه و تخصیص بافر را طبق برش‌های انتساب بافر سریالی شده، مقداردهی اولیه کنید.
  4. اجرا: توالی thunk آماده شده را روی جریان‌های دستگاه ارسال می‌کند.

تغییرات Pass، fusion، codegen و autotuning که طرحواره سریالی شده و معنای زمان اجرا را دست نخورده نگه می‌دارند، بر سازگاری AOT تأثیری ندارند.

عیب‌یابی: خرابی‌های بارگذاری که مربوط به اشکالات نسخه‌بندی نیستند

همه خطاهای بارگذاری فایل‌های اجرایی ناشی از رگرسیون‌های سریال‌سازی نیستند. دو عدم تطابق محیطی رایج، خطاهای زمان بارگذاری ایجاد می‌کنند:

  • عدم تطابق قابلیت محاسبه: GpuExecutable::FromProto تأیید می‌کند که gpu_compute_capability سریالی‌شده با دستگاه هدف مطابقت دارد. یک فایل اجرایی کامپایل‌شده برای NVIDIA Hopper نمی‌تواند روی NVIDIA Ampere اجرا شود.
  • عدم تطابق ABI زنجیره ابزار CUDA: CudaRuntimeAbiVersion::IsCompatibleWith بررسی می‌کند که نسخه‌های جعبه ابزار CUDA، cuDNN و CUB میزبان زمان اجرا، حداقل نسخه‌های ثبت شده در ExecutableAbiVersionProto را برآورده یا از آنها فراتر می‌روند. اگر درایور یا محیط کتابخانه میزبان قدیمی‌تر از هدف کامپایل باشد، بارگیری با FailedPreconditionError با شکست مواجه می‌شود.