mirror of
https://github.com/Niko1221/Strata.git
synced 2026-11-07 14:21:06 -10:00
Prefill: the fused ring's layer check is cached per CUDA device, so a layer split over unlike cards keeps MMQ's buffers where it must
fused_ring() decided once, in one function-local static bool, whether every layer of a native pack can take the fused int8 experts, and fused_layout() shrank the MoE buffers when it said yes. native_supported() answers for the card that is current: on CUDA with STRATA_PF_FUSED unset, moe_fused_iq.cu's dev_info() must say s120 with 80+ SMs. On a layer split over unlike cards the answer differs by stage - an 84-SM 5080 takes the fused kernels at 12.0, a 70-SM 5070 Ti beside it does not - and the flag came from whichever card was current at the first call. With the 5080 stage first, the buffers were shrunk for every stage and each 5070 Ti stage refused every chunk >= stream_all_min(): "Prefill: the fused layout's MoE buffers are too small for layer 25's expert path at a chunk of 8192 tokens" (2x 5080 + 2x 5070 Ti, --layer-split 12,25,37; layer 25 opens the first 5070 Ti stage). Short prompts passed, so the rig looked healthy. The answer is now cached per device (0 unknown, 1 covered, 2 not) under the caller's current device, in a std::atomic<int8_t> because the batch-slot threads read fused_ring() too. A card that can take the fused path keeps the shrink and its speed-up; a card that cannot keeps MMQ's full-size buffers. A homogeneous rig answers what the single global used to. Measured on the rig above (IQ3_S native pack, 512K context, --batch 4 --trim-stage-weights, STRATA_PIPED_MTP=1): fresh 29,486 and 29,484 token prompts read at 3,399.8 and 3,246.1 tok/s, decode 170.9 tok/s, no "too small" line in the log. Refs #3577.
This commit is contained in:
1 parent
5e8a4cca7d
commit
5d5e380c49
1 file changed
+17
-5
+17
-5
@@ -305,11 +305,23 @@ inline bool fused_ring() {
|
||||
// not cover (Unsloth UD-IQ4_XS's Q8_0 down projections) would run MMQ in them at the full chunk and overflow them
|
||||
// (garbage, an illegal memory access or a hung prompt on gfx1151). A pack with such a layer keeps MMQ's buffers;
|
||||
// its covered layers still take the fused kernels.
|
||||
static const bool all = [&lay] {
|
||||
for (const auto& f : lay.fmt)
|
||||
if (!fused::native_supported(f.gu_type, f.d_type)) return false;
|
||||
return !lay.fmt.empty();
|
||||
}();
|
||||
// PER DEVICE: native_supported() asks the CURRENT device (the SM count and compute capability of moe_fused_iq.cu's
|
||||
// dev_info()), so on a layer split over unlike cards the answer differs by stage: an 84-SM 5080 takes the fused
|
||||
// kernels at 12.0, a 70-SM 5070 Ti beside it does not. Cached as one global bool, the answer came from whichever
|
||||
// card happened to be current at the first call: on a split whose first stage was the 5080 the MoE buffers were
|
||||
// shrunk for every stage, and each 5070 Ti stage then failed every chunk >= stream_all_min() with "Prefill: the
|
||||
// fused layout's MoE buffers are too small for layer 25's expert path at a chunk of 8192 tokens" (measured
|
||||
// 2026-10-26, 2x 5080 + 2x 5070 Ti, --layer-split 12,25,37 - layer 25 opens the first 5070 Ti stage). Atomic
|
||||
// because the batch-slot threads read this too; a lost race recomputes the same per-device answer.
|
||||
static std::atomic<int8_t> per_dev[32]; // 0 unknown, 1 every layer covered on this device, 2 not
|
||||
int dev = 0;
|
||||
if (cudaGetDevice(&dev) != cudaSuccess || dev < 0 || dev >= 32) { (void) cudaGetLastError(); dev = 0; }
|
||||
const int8_t known = per_dev[dev].load(std::memory_order_relaxed);
|
||||
if (known != 0) return known == 1;
|
||||
bool all = !lay.fmt.empty();
|
||||
for (const auto& f : lay.fmt)
|
||||
if (!fused::native_supported(f.gu_type, f.d_type)) { all = false; break; }
|
||||
per_dev[dev].store(all ? 1 : 2, std::memory_order_relaxed);
|
||||
return all;
|
||||
}
|
||||
// the largest ring: 512 slots; 1024 with the Q2_0 pack's fused experts (P3's smaller buffers, measured there) - the
|
||||
|
||||
Reference in new issue
Block a user