Update QoLA/AITER #599
Conversation
| COMMAND sh -c | ||
| "tmp=$(mktemp /tmp/gitconfig.XXXXXX) || exit 1; \ | ||
| GIT_CONFIG_GLOBAL=$tmp git config --global --add safe.directory '*' >/dev/null 2>&1; \ | ||
| GIT_CONFIG_GLOBAL=$tmp PYTHONPATH=\"${__QOLA_DIR}:$PYTHONPATH\" '${Python_EXECUTABLE}' -m qola.cli checkout \ |
There was a problem hiding this comment.
Wouldn't it make sense to integrate safe.directory overriding to qola? The pattern with dubious ownership is probably not TE specific
There was a problem hiding this comment.
I worry that such behavior is a bit too authoritative for qola if that makes sense? My reasoning is that the permission scope here seems to be outside of qola and hence qola should not be the one in charge of it. I'm open to reconsidering that, but it's just my initial position.
There was a problem hiding this comment.
It is valid concern bearing in mind QoLA is intended to be reused by different components. May be make this behavior controllable then. It is OK to keep the things in TE, it will just require doing things this overriding twice - here and when build is called - BTW, there are comments there but not actual code change
There was a problem hiding this comment.
Sounds good, but can we do that in a separate PR to QoLA first?
There was a problem hiding this comment.
Now, with qola expected to create aiter dir runtime (it is not a part of repository tree), is there a reason to modify git config safe.directory? It was added for specific case: repository tree is checked out by a user and then shared with a container run with another user credentials.
| # commit QoLA will actually check out and build, not whatever happens to be | ||
| # the submodule's current HEAD at configure time. | ||
| set(__QOLA_MANIFEST "${CMAKE_CURRENT_LIST_DIR}/qola_manifest.toml") | ||
| set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${__QOLA_MANIFEST}") |
There was a problem hiding this comment.
AITER_SHA is not cached variable. Why is CMAKE_CONFIGURE_DEPENDS needed?
There was a problem hiding this comment.
I mainly have it so that direct cmake or ninja building will catch on manifest changes since I use it for incremental builds (and am thinking about including an incremental build option for TE's AITER FA backend). It's not strictly necessary, just a nice to have in such a workflow
There was a problem hiding this comment.
Will it also trigger re-executing of QoLA cli in the parent (ck_used_attn/ ) CMAkeLists.txt?
| return nullptr; | ||
| } | ||
| void* ptr = nullptr; | ||
| if(hipMallocAsync(&ptr, bytes, stream) != hipSuccess){ |
There was a problem hiding this comment.
Emm, if we let hip runtime to allocate and manage our buffers, this will create a series of issues. For example, if Pytorch or JAX users pre-allocate 97% of HBM, then our hipMallocAsync will return out of memory.
If what new aiter needs for fmha_args.workspace_alloc is a lambda, we can fake it to give jax/pytorch generated workspace buffer ptr?
| // callback thread, which holds runtime locks — calling any HIP API from it | ||
| // (including hipHostFree) deadlocks against concurrent main-thread HIP | ||
| // calls. Defer the free to ck_tile::pinned_host_releaser's worker thread. | ||
| fmha_args.pinned_host_alloc = [](size_t bytes) -> std::shared_ptr<void> { |
There was a problem hiding this comment.
Emm, why do they need host memory allocated? Is it for inference?
Again, can we fake the lambda to use pytorch/jax generated workspace?
VeeraRajasekhar
left a comment
There was a problem hiding this comment.
Verified that ROCm/rocm-libraries#6764 exists in the current pinned aiter commit.
| size_t head_dim_v, | ||
| int64_t window_size_left, | ||
| int64_t window_size_right, | ||
| bool is_training, bool cuda_graph) { |
There was a problem hiding this comment.
From my understanding, is_ck_backend_supported is the only consumer of the new graph-capture gate, but it's called without deterministic (TransformerEngine\transformer_engine\common\fused_attn_rocm\fused_attn.cpp line 320) even though nvte_get_fused_attn_backend has it in scope (TransformerEngine\transformer_engine\common\fused_attn_rocm\fused_attn.cpp line 282).
Since deterministic bwd forces the non-graph-safe CK v2 path, is_ck_bwd_graph_capture_safe cannot make the right call without it. See my other related comments above for what could be added to fix.
You should include here the bool deterministic as well
| is_v3_arch && | ||
| dropout == 0.f && | ||
| bias_type == NVTE_Bias_Type::NVTE_NO_BIAS && | ||
| max_seqlen_q >= 16; |
| // unaffected). Determinism also forces v2 but is invisible here, so it is handled | ||
| // on the framework side. | ||
| if(is_training && cuda_graph && | ||
| !is_ck_bwd_graph_capture_safe(bias_type, dropout, max_seqlen_q)){ |
There was a problem hiding this comment.
You should include here the deterministic as well
| static bool is_ck_bwd_graph_capture_safe( | ||
| NVTE_Bias_Type bias_type, | ||
| float dropout, | ||
| size_t max_seqlen_q) { |
There was a problem hiding this comment.
Add bool deterministic
| window_size_left, | ||
| window_size_right)){ | ||
| window_size_right, | ||
| is_training, cuda_graph)){ |
There was a problem hiding this comment.
Pass here the deterministic
| # graph capture this corner is invisible to the C++ backend selector (determinism | ||
| # is not part of its signature), so fall back to the unfused backend here. |
| fmha_args.d_sink_ptr = nullptr; | ||
| fmha_args.mask_type = static_cast<int>(static_cast<mask_enum>(args.attn_mask_type)); | ||
| fmha_args.use_asm_v3 = args.uses_bwd_v3; | ||
| // Mirrors AITER's small-seqlen guard at aiter/ops/mha.py:1689. |
There was a problem hiding this comment.
The next time AITER version is bumped this hardcoded line number will not be relevant anymore.
| void* ptr = nullptr; | ||
| if(hipHostMalloc(&ptr, bytes, hipHostMallocDefault) != hipSuccess){ | ||
| throw std::runtime_error("ck_fused_attn bwd: hipHostMalloc failed for AITER pinned host buffer."); | ||
| throw std::runtime_error("ck_fused_attn bwd: pinned host staging was not reserved and " |
There was a problem hiding this comment.
This message is specific for hipErrorStreamCaptureUnsupported only while there might be other allocation errors, so dispatch by hipGetLastError() is needed
There was a problem hiding this comment.
I've updated the error string to be more descriptive, lmk if this is sufficient.
| bool resolves_to_v3 = fmha_args.use_asm_v3 && !fmha_args.is_deterministic && | ||
| !fmha_args.has_dbias && fmha_args.bias_type == 0 && | ||
| !fmha_args.has_dropout && is_v3_arch; | ||
| if(!resolves_to_v3){ |
There was a problem hiding this comment.
W/o this throw the whole graph capture safety net is useless
There was a problem hiding this comment.
The graph capture safety net actually needs to be removed entirely since now the CK kernels provided should be graph safe. I've updated the PR to remove it.
f004fcf to
bb0797a
Compare
a8c5290 to
679283a
Compare
# Conflicts: # 3rdparty/QoLA # transformer_engine/common/ck_fused_attn/CMakeLists.txt # transformer_engine/common/ck_fused_attn/aiter_prebuilt.cmake # transformer_engine/common/ck_fused_attn/check_aiter_mha_args.py # transformer_engine/common/ck_fused_attn/qola_manifest.toml
| # QoLA-managed AITER source tree to that commit before any consumer reads it | ||
| # (header validation below, header includes for the .cpp build later, and | ||
| # QoLA's own kernel build if the prebuilt cache misses). | ||
| include("${CMAKE_CURRENT_LIST_DIR}/aiter_prebuilt.cmake") |
There was a problem hiding this comment.
It is not needed here - AITER_SHA is determined above, cache directory is only needed if neither AITER_MHA_PATH is set nor CK-JIT is enabled, so it is included at line 158
| COMMAND sh -c | ||
| "tmp=$(mktemp /tmp/gitconfig.XXXXXX) || exit 1; \ | ||
| GIT_CONFIG_GLOBAL=$tmp git config --global --add safe.directory '*' >/dev/null 2>&1; \ | ||
| GIT_CONFIG_GLOBAL=$tmp PYTHONPATH=\"${__QOLA_DIR}:$PYTHONPATH\" '${Python_EXECUTABLE}' -m qola.cli checkout \ |
There was a problem hiding this comment.
Now, with qola expected to create aiter dir runtime (it is not a part of repository tree), is there a reason to modify git config safe.directory? It was added for specific case: repository tree is checked out by a user and then shared with a container run with another user credentials.
When CK-JIT cannot find workspace-query symbols (dq_ws_host_size, needs_zero_dq_acc) for a kernel variant — which happens for deterministic kernels when d_v differs from d_qk (e.g. d_qk=128, d_v=64) — AITER's mha_bwd_workspace_size() reports only the non-deterministic workspace size (~132 MiB), causing the kernel to overflow into adjacent XLA buffers and corrupt the forward output (NaN in value_and_grad). Fix: add the old explicit dq_acc formula as a floor in ck_attn_bwd_workspace_size(), matching the per-sequence kv split count used by the CK v2 deterministic accumulation algorithm. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
ipanfilo
left a comment
There was a problem hiding this comment.
It seems there are still some numeric failures in determenistic path
|
The latest fixes for determinism seem not helping on gfx942 |
Description
Updates QoLA as well as moves up the pinned AITER commit
Fixes # (issue)
Type of change
Changes
Please list the changes introduced in this PR:
Checklist: