Skip to content

Commit ad8db49

Browse files
committed
Drop the unused kv-head override from the shard-size helpers
The override existed because get_shard_size read a process-wide num_kv_heads that was only set during AutoTP replacement. The inference engine patches the alibi helpers before that happens, so it probed the head count itself and passed it in to bypass the uninitialized global. That was the parameter's only caller. With the count carried by a per-model AutoTPMeta, the alibi path receives its own model's value like everyone else, and the previous commit removed the round trip that read meta.num_kv_heads only to pass it straight back. Nothing outside tp_shard supplies the argument now, so remove it and the two tests written against it; get_shard_size has a single source for the head count again. Signed-off-by: Guokai Ma <guokai.ma@intel.com>
1 parent 9999f68 commit ad8db49

2 files changed

Lines changed: 8 additions & 32 deletions

File tree

deepspeed/module_inject/tp_shard.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def from_model_config(cls, model_config, tp_grain_size: int = 1) -> "AutoTPMeta"
8282
tp_grain_size=tp_grain_size)
8383

8484

85-
def get_shard_size(total_size, mp_size, meta: AutoTPMeta, name=None, rank=None, mp_group=None, eff_num_kv_heads=None):
85+
def get_shard_size(total_size, mp_size, meta: AutoTPMeta, name=None, rank=None, mp_group=None):
8686
"""Size of one shard of ``total_size`` split across a tensor-parallel group of ``mp_size``.
8787
8888
``meta`` carries this model's ``num_kv_heads`` / ``tp_grain_size`` so the split is stable
@@ -92,14 +92,8 @@ def get_shard_size(total_size, mp_size, meta: AutoTPMeta, name=None, rank=None,
9292
``rank`` is the rank *within the tensor-parallel group*, i.e. in ``[0, mp_size)``, matching
9393
``dist.get_rank(group=mp_group)`` and the index used by ``get_shard_size_list``. It is not a
9494
global rank.
95-
96-
``eff_num_kv_heads`` is the head count this split is actually aligned to; it defaults to
97-
``meta.num_kv_heads``. Passing it explicitly lets callers split fused sub-parameters (Q/K/V)
98-
against their respective head counts without reimplementing the KV-head-aligned partition
99-
logic at the call site.
10095
"""
101-
if eff_num_kv_heads is None:
102-
eff_num_kv_heads = meta.num_kv_heads
96+
num_kv_heads = meta.num_kv_heads
10397
tp_grain_size = meta.tp_grain_size
10498
last_linear = ["lm_head", "embed_out"]
10599
# MoE MLP layer use near even division will get better perf.
@@ -117,10 +111,10 @@ def get_shard_size(total_size, mp_size, meta: AutoTPMeta, name=None, rank=None,
117111
raise ValueError("get_shard_size requires a group-local rank or process group when mp_size "
118112
f"({mp_size}) differs from the distributed world size ({world_size}).")
119113
rank = dist.get_rank()
120-
if eff_num_kv_heads is not None and total_size % eff_num_kv_heads == 0 and "mlp" not in str(name) and \
114+
if num_kv_heads is not None and total_size % num_kv_heads == 0 and "mlp" not in str(name) and \
121115
str(name) not in last_linear and not_moe_mlp_layer:
122-
my_slices = (eff_num_kv_heads // mp_size) + (1 if rank < (eff_num_kv_heads % mp_size) else 0)
123-
return total_size * my_slices // eff_num_kv_heads
116+
my_slices = (num_kv_heads // mp_size) + (1 if rank < (num_kv_heads % mp_size) else 0)
117+
return total_size * my_slices // num_kv_heads
124118
else:
125119
if total_size >= tp_grain_size:
126120
grain_size, remainder = divmod(total_size, tp_grain_size)
@@ -135,16 +129,14 @@ def get_shard_size(total_size, mp_size, meta: AutoTPMeta, name=None, rank=None,
135129
return total_size // mp_size + (1 if rank < (total_size % mp_size) else 0)
136130

137131

138-
def get_shard_size_list(total_size, mp_size, meta: AutoTPMeta, name=None, eff_num_kv_heads=None):
132+
def get_shard_size_list(total_size, mp_size, meta: AutoTPMeta, name=None):
139133
shard_sizes = []
140-
if eff_num_kv_heads is None:
141-
eff_num_kv_heads = meta.num_kv_heads
142134
for i in range(mp_size):
143-
shard_sizes.append(get_shard_size(total_size, mp_size, meta, name, i, eff_num_kv_heads=eff_num_kv_heads))
135+
shard_sizes.append(get_shard_size(total_size, mp_size, meta, name, i))
144136
# Shards must tile the dimension exactly, otherwise the partitioned weights no longer
145137
# reconstruct the original tensor.
146138
assert sum(shard_sizes) == total_size, (
147139
f"AutoTP shard sizes {shard_sizes} for layer '{name}' do not sum to the dimension size "
148140
f"{total_size} with tp_size={mp_size}, tp_grain_size={meta.tp_grain_size} and "
149-
f"num_kv_heads={eff_num_kv_heads}.")
141+
f"num_kv_heads={meta.num_kv_heads}.")
150142
return shard_sizes

tests/unit/module_inject/test_tp_shard.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,3 @@ def test_shard_size_refuses_to_guess_subgroup_rank(monkeypatch):
6464

6565
with pytest.raises(ValueError, match="group-local rank or process group"):
6666
get_shard_size(12, 2, AutoTPMeta())
67-
68-
69-
def test_explicit_num_kv_heads_overrides_meta():
70-
# Fused Q/K/V sub-parameters are split against their own head counts, which differ from
71-
# the model-wide kv-head count carried by the meta.
72-
meta = AutoTPMeta(num_kv_heads=2)
73-
74-
assert get_shard_size_list(384, 4, meta, "self_attn.q_proj", eff_num_kv_heads=6) == [128, 128, 64, 64]
75-
76-
77-
def test_explicit_num_kv_heads_matches_meta_value():
78-
expected = get_shard_size_list(384, 4, AutoTPMeta(num_kv_heads=6), "self_attn.q_proj")
79-
80-
actual = get_shard_size_list(384, 4, AutoTPMeta(), "self_attn.q_proj", eff_num_kv_heads=6)
81-
82-
assert actual == expected

0 commit comments

Comments
 (0)