Skip to content

Commit de5c56d

Browse files
committed
Resolve the rest of the rebase conflict
1 parent 00829e8 commit de5c56d

4 files changed

Lines changed: 98 additions & 42 deletions

File tree

megatron/core/inference/contexts/dynamic_context.py

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -928,16 +928,20 @@ def initialize_all_tensors(self) -> None:
928928
# transferred to GPU each step via transfer_bookkeeping_to_gpu().
929929
# Layout matches ContextGPUView._buf so a single cudaMemcpyAsync
930930
# suffices. Int64 token fields come first (8-byte aligned automatically),
931-
# then int32 token fields, then int32 request-staging fields.
932-
# token_to_input_ids (int64, max_tokens)
933-
# token_to_pos_ids (int64, max_tokens)
934-
# token_to_block_idx (int32, max_tokens)
935-
# token_to_local_position_within_kv_block (int32, max_tokens)
936-
# token_to_request_idx (int32, max_tokens)
937-
# token_to_position_in_request (int32, max_tokens)
938-
# request_in_prefill_status (staging) (int32, max_requests)
939-
# request_query_lengths (staging) (int32, max_requests)
940-
# request_kv_length_offsets (staging) (int32, max_requests)
931+
# then int32 token fields, then int32/float32 request-staging fields.
932+
# token_to_input_ids (int64, max_tokens)
933+
# token_to_pos_ids (int64, max_tokens)
934+
# token_to_block_idx (int32, max_tokens)
935+
# token_to_local_position_within_kv_block (int32, max_tokens)
936+
# token_to_request_idx (int32, max_tokens)
937+
# token_to_position_in_request (int32, max_tokens)
938+
# request_in_prefill_status (staging) (int32, max_requests)
939+
# request_query_lengths (staging) (int32, max_requests)
940+
# request_kv_length_offsets (staging) (int32, max_requests)
941+
# temperature (staging) (float32, max_requests)
942+
# top_k (staging) (int32, max_requests)
943+
# top_p (staging) (float32, max_requests)
944+
# active_request_last_token_idxs (alias) (int32, max_requests)
941945
#
942946
# Token fields are aliased with the source-of-truth attributes
943947
# (`self.token_to_input_ids`, etc.) because the forward pass reads
@@ -948,7 +952,8 @@ def initialize_all_tensors(self) -> None:
948952
# slice from the persistent `request_*` tensors above.
949953
_tok_int64_bytes = self.max_tokens * 8
950954
_tok_int32_bytes = self.max_tokens * 4
951-
_req_int32_bytes = self.max_requests * 4
955+
# Request-level fields are all 4 bytes wide (5 int32 + 2 float32 = 7 fields).
956+
_req_4byte_bytes = self.max_requests * 4
952957
# MHA section: 5 fields (int32) shared between GraphedMHAMetadata and
953958
# NonGraphedMHAMetadata. max_bs == max_requests.
954959
_mha_query_lengths_bytes = self.max_requests * 4
@@ -983,7 +988,7 @@ def initialize_all_tensors(self) -> None:
983988
_total_bytes = (
984989
2 * _tok_int64_bytes
985990
+ 4 * _tok_int32_bytes
986-
+ 3 * _req_int32_bytes
991+
+ 7 * _req_4byte_bytes
987992
+ _mha_query_lengths_bytes
988993
+ _mha_cu_query_seq_lengths_bytes
989994
+ _mha_kv_seq_lengths_bytes
@@ -1043,19 +1048,40 @@ def initialize_all_tensors(self) -> None:
10431048
# CPU (refreshed from persistent tensors in transfer_bookkeeping_to_gpu);
10441049
# read-only on GPU via matching slots in ContextGPUView._buf.
10451050
self._staging_request_in_prefill_status = self._cpu_bookkeeping_buf[
1046-
_off : _off + _req_int32_bytes
1051+
_off : _off + _req_4byte_bytes
10471052
].view(torch.int32)
1048-
_off += _req_int32_bytes
1053+
_off += _req_4byte_bytes
10491054
self._staging_request_query_lengths = self._cpu_bookkeeping_buf[
1050-
_off : _off + _req_int32_bytes
1055+
_off : _off + _req_4byte_bytes
10511056
].view(torch.int32)
1052-
_off += _req_int32_bytes
1057+
_off += _req_4byte_bytes
10531058
self._staging_request_kv_length_offsets = self._cpu_bookkeeping_buf[
1054-
_off : _off + _req_int32_bytes
1059+
_off : _off + _req_4byte_bytes
10551060
].view(torch.int32)
1056-
_off += _req_int32_bytes
1061+
_off += _req_4byte_bytes
10571062

1058-
self.active_request_last_token_idxs = torch.empty_like(self.request_query_lengths)
1063+
# Sampling-parameter staging slots, refreshed from `active_request_metadata`
1064+
# in transfer_bookkeeping_to_gpu(). FlashInfer reads these via
1065+
# `gpu_view.{temperature, top_k, top_p}`.
1066+
self._staging_temperature = self._cpu_bookkeeping_buf[_off : _off + _req_4byte_bytes].view(
1067+
torch.float32
1068+
)
1069+
_off += _req_4byte_bytes
1070+
self._staging_top_k = self._cpu_bookkeeping_buf[_off : _off + _req_4byte_bytes].view(
1071+
torch.int32
1072+
)
1073+
_off += _req_4byte_bytes
1074+
self._staging_top_p = self._cpu_bookkeeping_buf[_off : _off + _req_4byte_bytes].view(
1075+
torch.float32
1076+
)
1077+
_off += _req_4byte_bytes
1078+
1079+
# Per-request last-token row indices. Aliased with the matching gpu_view slot:
1080+
# build_active_slices/pad_active_slices populate this CPU view.
1081+
self.active_request_last_token_idxs = self._cpu_bookkeeping_buf[
1082+
_off : _off + _req_4byte_bytes
1083+
].view(torch.int32)
1084+
_off += _req_4byte_bytes
10591085

10601086
# Static tensor addresses to make `last_token_logits` graphable with speculative decoding.
10611087
max_logit_idxs = self.max_requests * (self.num_speculative_tokens + 1)
@@ -2244,7 +2270,7 @@ def transfer_bookkeeping_to_gpu(self) -> None:
22442270
All copies use non_blocking=True with pinned CPU memory. CUDA stream
22452271
ordering guarantees the forward pass sees completed transfers.
22462272
2247-
The 9 bookkeeping fields are backed by one contiguous pinned CPU buffer
2273+
The bookkeeping fields are backed by one contiguous pinned CPU buffer
22482274
and one contiguous GPU buffer; a single cudaMemcpyAsync suffices.
22492275
Request-level staging slots are refreshed from the persistent CPU
22502276
tensors immediately before the H2D (GPU reads them at `[:n_active]`
@@ -2255,16 +2281,25 @@ def transfer_bookkeeping_to_gpu(self) -> None:
22552281
padded_active = max(n_active, self.padded_active_request_count)
22562282

22572283
# Refresh request-level staging slots from the persistent CPU source.
2258-
# CPU-to-CPU slice assignment on pinned memory (~7.5 KB total for 3
2259-
# int32 fields at max_requests=624). Negligible vs. the launch overhead
2260-
# we save by merging 9 H2D memcpys into 1.
2284+
# CPU-to-CPU slice assignment on pinned memory (~15 KB total for 6
2285+
# 4-byte fields at max_requests=624). Negligible vs. the launch overhead
2286+
# we save by merging the H2D memcpys into 1.
22612287
self._staging_request_in_prefill_status[:n_active] = self.request_in_prefill_status_tensor[
22622288
active_slice
22632289
]
22642290
self._staging_request_query_lengths[:n_active] = self.request_query_lengths[active_slice]
22652291
self._staging_request_kv_length_offsets[:n_active] = self.request_kv_length_offsets[
22662292
active_slice
22672293
]
2294+
# Sampling-parameter staging slots: read from `active_request_metadata`,
2295+
# which `build_active_slices` + `pad_active_slices` already populated for
2296+
# `[:padded_active]` (active values + neutral padding defaults).
2297+
self._staging_temperature[:padded_active] = self.active_request_metadata["temperature"][
2298+
:padded_active
2299+
]
2300+
self._staging_top_k[:padded_active] = self.active_request_metadata["top_k"][:padded_active]
2301+
self._staging_top_p[:padded_active] = self.active_request_metadata["top_p"][:padded_active]
2302+
22682303
# Full-iteration CUDA graphs may have captured GPU consumers with the
22692304
# padded graph request count. Keep those padded staging rows bounded so
22702305
# graph replay never builds indices from stale request lengths.

megatron/core/inference/contexts/gpu_view.py

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ class ContextGPUView:
1717
``context.foo`` -> CPU (source of truth, used by bookkeeping)
1818
``context.gpu_view.foo`` -> GPU (snapshot, used by forward pass)
1919
20-
Layout note: the 9 bookkeeping fields are backed by a single contiguous
20+
Layout note: the bookkeeping fields are backed by a single contiguous
2121
``uint8`` buffer (``self._buf``). Each field is a ``view(dtype)`` onto a
2222
slice of that buffer. This matches the pinned-CPU-buffer layout in
2323
:class:`DynamicInferenceContext` so that the per-step H2D transfer is a
24-
single ``cudaMemcpyAsync`` instead of nine small ones.
24+
single ``cudaMemcpyAsync`` instead of one per field.
2525
"""
2626

2727
def __init__(
@@ -39,7 +39,10 @@ def __init__(
3939
# max_mamba_chunks == 0).
4040
tok_int64_bytes = max_tokens * 8 # 2 fields of int64 = 8 bytes/elem
4141
tok_int32_bytes = max_tokens * 4 # 4 fields of int32 = 4 bytes/elem
42-
req_int32_bytes = max_requests * 4 # 3 fields of int32
42+
# Request-level fields are all 4 bytes wide. 3 int32 (in_prefill_status,
43+
# query_lengths, kv_length_offsets) + 1 int32 (top_k) + 2 float32
44+
# (temperature, top_p) + 1 int32 (active_request_last_token_idxs) = 7 fields.
45+
req_4byte_bytes = max_requests * 4
4346

4447
# MHA section: 5 fields shared by both graphed and non-graphed MHAMetadata
4548
# (only one is active per step, so sharing storage is fine).
@@ -90,7 +93,7 @@ def __init__(
9093
total_bytes = (
9194
2 * tok_int64_bytes
9295
+ 4 * tok_int32_bytes
93-
+ 3 * req_int32_bytes
96+
+ 7 * req_4byte_bytes
9497
+ mha_query_lengths_bytes
9598
+ mha_cu_query_seq_lengths_bytes
9699
+ mha_kv_seq_lengths_bytes
@@ -128,12 +131,28 @@ def __init__(
128131
off += tok_int32_bytes
129132

130133
# Request-level tensors (consumed by sampling, log-probs, speculative verification, MTP).
131-
self.request_in_prefill_status = self._buf[off : off + req_int32_bytes].view(torch.int32)
132-
off += req_int32_bytes
133-
self.request_query_lengths = self._buf[off : off + req_int32_bytes].view(torch.int32)
134-
off += req_int32_bytes
135-
self.request_kv_length_offsets = self._buf[off : off + req_int32_bytes].view(torch.int32)
136-
off += req_int32_bytes
134+
self.request_in_prefill_status = self._buf[off : off + req_4byte_bytes].view(torch.int32)
135+
off += req_4byte_bytes
136+
self.request_query_lengths = self._buf[off : off + req_4byte_bytes].view(torch.int32)
137+
off += req_4byte_bytes
138+
self.request_kv_length_offsets = self._buf[off : off + req_4byte_bytes].view(torch.int32)
139+
off += req_4byte_bytes
140+
# Sampling parameters (consumed by FlashInfer sampling).
141+
# Mirror the active slice of `active_request_metadata[{label}]`;
142+
# padded slots get neutral defaults from `pad_active_slices` (T=1.0, top_k=0, top_p=0.0).
143+
self.temperature = self._buf[off : off + req_4byte_bytes].view(torch.float32)
144+
off += req_4byte_bytes
145+
self.top_k = self._buf[off : off + req_4byte_bytes].view(torch.int32)
146+
off += req_4byte_bytes
147+
self.top_p = self._buf[off : off + req_4byte_bytes].view(torch.float32)
148+
off += req_4byte_bytes
149+
# Per-request last-token row indices (consumed by sampling kernels as `gather_indices`).
150+
# The CPU side of this slot IS `context.active_request_last_token_idxs`,
151+
# populated by `build_active_slices` and `pad_active_slices`.
152+
self.active_request_last_token_idxs = self._buf[off : off + req_4byte_bytes].view(
153+
torch.int32
154+
)
155+
off += req_4byte_bytes
137156

138157
# MHA flash-attention metadata (shared between GraphedMHAMetadata and
139158
# NonGraphedMHAMetadata — only one is active per step).

megatron/core/inference/sampling/flashinfer_sampling.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,18 @@ def sample_kernel(
6666
# CudaGraphManager consumes these args, if it exists.
6767
del eager, cache_key
6868

69-
# Read GPU sampling parameters directly from `context.active_request_metadata`.
70-
md = context.active_request_metadata
69+
# Read GPU sampling parameters from the per-step gpu_view mirror. The
70+
# CPU source-of-truth (`active_request_metadata`) is pinned but resident
71+
# on CPU, so reading it here would mix devices with `logits`.
72+
gv = context.gpu_view
7173
if token_to_request_index is None:
72-
temperature = md["temperature"][:n]
73-
top_k = md["top_k"][:n]
74-
top_p = md["top_p"][:n]
74+
temperature = gv.temperature[:n]
75+
top_k = gv.top_k[:n]
76+
top_p = gv.top_p[:n]
7577
else:
76-
temperature = md["temperature"][token_to_request_index]
77-
top_k = md["top_k"][token_to_request_index]
78-
top_p = md["top_p"][token_to_request_index]
78+
temperature = gv.temperature[token_to_request_index]
79+
top_k = gv.top_k[token_to_request_index]
80+
top_p = gv.top_p[token_to_request_index]
7981

8082
# Clamp temperature to avoid division by 0.
8183
temperature = temperature.clamp(min=1e-6)

megatron/core/inference/text_generation_controllers/text_generation_controller.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ def _dynamic_step_sample_logits(self):
10521052
gather_indices = (
10531053
None
10541054
if context.config.materialize_only_last_token_logits
1055-
else context.active_request_last_token_idxs
1055+
else context.gpu_view.active_request_last_token_idxs
10561056
)
10571057
self._sampled_tokens_cuda = self._sampling.sample_kernel(
10581058
self._all_logits_cuda.squeeze(0),

0 commit comments

Comments
 (0)