已合并
0312MoE大融合方案 #4
0312MoE大融合方案 #4
已合并
Dawn952创建于 3月12日
共 7 个文件变更+278-170
Mmindie_llm/runtime/layers/fused_moe/fused_moe.py+2-5文件内容审核中,请稍后刷新重试
@@ -1,7 +1,3 @@
1-# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
2-# SPDX-License-Identifier: Apache-2.0
3-#
4-# Implement part of this file based on vllm-project/vllm
5# Copyright (c) Huawei Technologies Co., Ltd. 2025-2026. All rights reserved.1# Copyright (c) Huawei Technologies Co., Ltd. 2025-2026. All rights reserved.
6# MindIE is licensed under Mulan PSL v2.2# MindIE is licensed under Mulan PSL v2.
7# You can use this software according to the terms and conditions of the Mulan PSL v2.3# You can use this software according to the terms and conditions of the Mulan PSL v2.
@@ -12,32 +8,21 @@
12# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.8# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13# See the Mulan PSL v2 for more details.9# See the Mulan PSL v2 for more details.
14 10 
15-from enum import Enum11+from typing import Optional, Dict, Type
16-from typing import Optional
17 12 
18-from mindie_llm.runtime.utils.npu.device_utils import DeviceType, get_npu_node_info
19from mindie_llm.runtime.layers.fused_moe.token_dispatcher import (13from mindie_llm.runtime.layers.fused_moe.token_dispatcher import (
20 MoETokenDispatcher,14 MoETokenDispatcher,
21 TokenDispatcherWithAllGather,15 TokenDispatcherWithAllGather,
22 TokenDispatcherWithMC2,16 TokenDispatcherWithMC2,
23 TokenDispatcherWithAll2AllV17 TokenDispatcherWithAll2AllV
24)18)
25-from mindie_llm.runtime.utils.distributed import get_parallel_info_manager19+from mindie_llm.runtime.layers.fused_moe.token_dispatcher import MoETokenDispatcher
26-from mindie_llm.runtime.utils.distributed.parallel_info_manager import ParallelType20+from mindie_llm.runtime.layers.fused_moe.moe_comm_strategy import MOE_COMM_STRATEGIES, MoECommType
27-from mindie_llm.runtime.layers.quantization.ms_model_slim.quant_type import QuantType
28-from mindie_llm.runtime.model_runner.forward_context import get_forward_context
29-from mindie_llm.runtime.model_runner.forward_context_exp import get_mc2_token_capacity
30from mindie_llm.utils.log.logging import logger21from mindie_llm.utils.log.logging import logger
31 22 
32 23 
33-class MoECommType(Enum):24+# Communication type to dispatcher class mapping
34- ALLGATHER = "allgather"25+_COMM_TYPE_TO_DISPATCHER: Dict[MoECommType, Type[MoETokenDispatcher]] = {
35- MC2 = "mc2"
36- ALLTOALL = "all2all"
37- FUSED_ALLTOALL = "fused_all2all"
38- 
39- 
40-_COMM_TYPE_TO_DISPATCHER = {
41 MoECommType.ALLGATHER: TokenDispatcherWithAllGather,26 MoECommType.ALLGATHER: TokenDispatcherWithAllGather,
42 MoECommType.MC2: TokenDispatcherWithMC2,27 MoECommType.MC2: TokenDispatcherWithMC2,
43 MoECommType.ALLTOALL: TokenDispatcherWithAll2AllV,28 MoECommType.ALLTOALL: TokenDispatcherWithAll2AllV,
@@ -46,80 +31,47 @@ _COMM_TYPE_TO_DISPATCHER = {
46 31 
47def select_moe_comm_method(32def select_moe_comm_method(
48 quant_type: Optional[str] = None,33 quant_type: Optional[str] = None,
49- is_fused_op_enabled: bool = False) -> Optional[MoECommType]:34+ max_num_tokens_per_device: Optional[int] = None
50- """1. If expert parallel is not enabled, we use all-gather since MC2 and all-to-all35+) -> Optional[MoECommType]:
51- are designed for expert parallelism.36+ """Select optimal MoE communication method.
52- 2. If expert parallel is enabled, we need to consider the soc version and the37+
53- number of tokens. This is based on the observation that all-gather is more
54- efficient than all-to-all when running on _910B.
55- 
56- a. For _910B, we choose from MC2 and all-gather.
57- 
58- b. For _910_93, we choose from MC2 and all-to-all.
59- 
60- In both cases, we use MC2 when in prefill phase.
61- 
62 Args:38 Args:
63- quant_type (Optional[str], optional): The quantization type. Defaults to None.39+ quant_type: Quantization type (e.g., W4A8_DYNAMIC).
64- 40+ max_num_tokens_per_device: Max tokens per device limit.
65- Raises:41+
66- ValueError: If the soc version is unsupported.
67- 
68 Returns:42 Returns:
69- MoECommType: The selected MoE communication method.43+ Selected MoECommType.
44+
45+ Raises:
46+ RuntimeError: No applicable strategy found.
70 """47 """
71- ascend_device_type = get_npu_node_info().get_device_type()48+ # Strategy traversal: return first applicable strategy
72- parallel_info_manager = get_parallel_info_manager()49+ for strategy_cls in MOE_COMM_STRATEGIES:
73- is_prefill = get_forward_context().is_prefill50+ if strategy_cls.is_applicable(
74- enable_expert_parallel = parallel_info_manager.get(ParallelType.MOE_EP).is_enabled()51+ quant_type=quant_type,
75- 52+ max_num_tokens_per_device=max_num_tokens_per_device
76- # NOTE: Due to unsolved error for mc2 in prefill phase, we disable mc2 in prefill phase.53+ ):
77- # NOTE: Temporarily not use parameter num_tokens to select MoECommType.54+ selected = strategy_cls.get_comm_type()
78- if not enable_expert_parallel:55+ return selected
79- moe_comm_type = MoECommType.ALLGATHER56+ error_msg = (
80- elif ascend_device_type in {DeviceType.ASCEND_910B}:57+ "MoE strategy selection failed, please check the config."
81- if not is_prefill and parallel_info_manager.world_size >= 16:58+ )
82- moe_comm_type = MoECommType.MC259+ logger.error(error_msg)
83- else:60+ raise RuntimeError(error_msg)
84- if quant_type == QuantType.W4A8_DYNAMIC:
85- moe_comm_type = MoECommType.ALLTOALL
86- else:
87- moe_comm_type = MoECommType.ALLGATHER
88- elif ascend_device_type in {DeviceType.ASCEND_910_93}:
89- # NOTE: Fused op is not enabled in prefill stage
90- if get_forward_context().is_prefill:
91- moe_comm_type = MoECommType.ALLTOALL
92- elif get_forward_context().batch_descriptor.num_tokens <= get_mc2_token_capacity():
93- moe_comm_type = MoECommType.MC2
94- else:
95- moe_comm_type = MoECommType.ALLTOALL
96- else:
97- raise ValueError(f"Unsupported soc_version: {ascend_device_type}")
98- 
99- # NOTE: MoECommType.ALLGATHER: Currently does not support enabling DP.
100- if moe_comm_type == MoECommType.ALLGATHER and parallel_info_manager.get(ParallelType.ATTN_DP).is_enabled():
101- moe_comm_type = MoECommType.ALLTOALL
102- logger.debug('Currently do not support MoECommType.ALLGATHER with dp.')
103- 
104- # NOTE: MoECommType.MC2 and MoECommType.ALLTOALL: Do not support moe_tp > 1,
105- # and require flash_comm to be enabled.
106- if moe_comm_type in (MoECommType.MC2, MoECommType.ALLTOALL):
107- if parallel_info_manager.get(ParallelType.MOE_TP).is_enabled():
108- err_msg = 'MoECommType.MC2 and MoECommType.ALLTOALL: Do not support moe_tp > 1,'
109- # try to change to MoECommType.ALLGATHER
110- if parallel_info_manager.get(ParallelType.ATTN_DP).is_enabled():
111- logger.error(err_msg)
112- raise RuntimeError(err_msg)
113- else:
114- logger.warning(err_msg)
115- moe_comm_type = MoECommType.ALLGATHER
116- 
117- return moe_comm_type
118 61 
119 62 
120def get_cached_dispatcher(63def get_cached_dispatcher(
121- moe_comm_type: Optional[MoECommType]) -> Optional[MoETokenDispatcher]:64+ moe_comm_type: Optional[MoECommType]
65+) -> Optional[MoETokenDispatcher]:
66+ """Get dispatcher instance for given communication type.
67+
68+ Args:
69+ moe_comm_type: Communication type enum.
70+
71+ Returns:
72+ Dispatcher instance or None if type unsupported.
73+ """
122 if moe_comm_type is None or moe_comm_type not in _COMM_TYPE_TO_DISPATCHER:74 if moe_comm_type is None or moe_comm_type not in _COMM_TYPE_TO_DISPATCHER:
123 return None75 return None
124 dispatcher_cls = _COMM_TYPE_TO_DISPATCHER[moe_comm_type]76 dispatcher_cls = _COMM_TYPE_TO_DISPATCHER[moe_comm_type]
125- return dispatcher_cls()77+ return dispatcher_cls()
@@ -0,0 +1,183 @@
1+# Copyright (c) Huawei Technologies Co., Ltd. 2025-2026. All rights reserved.
2+# MindIE is licensed under Mulan PSL v2.
3+# You can use this software according to the terms and conditions of the Mulan PSL v2.
4+# You may obtain a copy of Mulan PSL v2 at:
5+# http://license.coscl.org.cn/MulanPSL2
6+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
7+# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
8+# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
9+# See the Mulan PSL v2 for more details.
10+ 
11+from typing import Optional
12+ 
13+from enum import Enum
14+from mindie_llm.runtime.utils.npu.device_utils import DeviceType
15+from mindie_llm.runtime.layers.quantization.ms_model_slim.quant_type import QuantType
16+from mindie_llm.runtime.model_runner.forward_context_exp import get_mc2_token_capacity
17+from mindie_llm.utils.log.logging import logger
18+ 
19+from mindie_llm.runtime.model_runner.forward_context import get_forward_context
20+from mindie_llm.runtime.utils.distributed import get_parallel_info_manager
21+from mindie_llm.runtime.utils.distributed.parallel_info_manager import ParallelType
22+from mindie_llm.runtime.utils.npu.device_utils import get_npu_node_info
23+ 
24+ 
25+class MoECommType(Enum):
26+ """Supported MoE communication operator types."""
27+ ALLGATHER = "allgather"
28+ MC2 = "mc2"
29+ ALLTOALL = "all2all"
30+ FUSED_ALLTOALL = "fused_all2all"
31+ FUSED_MC2 = "fused_mc2"
32+ 
33+ 
34+class MoECommStrategyBase:
35+ """Base class for MoE communication strategy selection."""
36+
37+ @staticmethod
38+ def is_applicable(quant_type: Optional[str], max_num_tokens_per_device: Optional[int]) -> bool:
39+ """Check if strategy applies to given context."""
40+ raise NotImplementedError
41+
42+ @staticmethod
43+ def get_comm_type() -> MoECommType:
44+ """Return communication type for this strategy."""
45+ raise NotImplementedError
46+ 
47+ 
48+class FusedMC2Strategy(MoECommStrategyBase):
49+ """Fused MC2 strategy: highest priority for Ascend 910C.
50+
51+ Requirements: EP group size <= 32, no MoE TP, tokens within capacity.
52+ """
53+
54+ @staticmethod
55+ def is_applicable(quant_type: Optional[str], max_num_tokens_per_device: Optional[int]) -> bool:
56+ device_type = get_npu_node_info().get_device_type()
57+ parallel_mgr = get_parallel_info_manager()
58+ forward_ctx = get_forward_context()
59+
60+ # EP must be enabled for any MoE communication strategy
61+ if not parallel_mgr.get(ParallelType.MOE_EP).is_enabled():
62+ return False
63+ # Hardware constraint: only Ascend 910C (910_93) supports fused MC2
64+ if device_type != DeviceType.ASCEND_910_93:
65+ return False
66+
67+ # EP group size limit for fused operator efficiency
68+ is_ep_valid = parallel_mgr.get(ParallelType.MOE_EP_MC2).group_size <= 32
69+ # Token count must fit within per-device capacity
70+ tp_size = parallel_mgr.get(ParallelType.ATTN_TP).group_size
71+ num_tokens_per_device = (forward_ctx.batch_descriptor.num_tokens + tp_size - 1) // tp_size
72+ is_num_tokens_valid = num_tokens_per_device <= max_num_tokens_per_device
73+ if not (is_ep_valid and is_num_tokens_valid):
74+ return False
75+ # Incompatible with MoE TP parallelism
76+ if parallel_mgr.get(ParallelType.MOE_TP).is_enabled():
77+ return False
78+ return True
79+
80+ @staticmethod
81+ def get_comm_type() -> MoECommType:
82+ return MoECommType.FUSED_MC2
83+ 
84+ 
85+class MC2Strategy(MoECommStrategyBase):
86+ """MC2 strategy: for Ascend 910B/910C decode phase.
87+
88+ 910B: requires world size >= 16. 910C: strict token capacity check.
89+ """
90+
91+ @staticmethod
92+ def is_applicable(quant_type: Optional[str], max_num_tokens_per_device: Optional[int]) -> bool:
93+ device_type = get_npu_node_info().get_device_type()
94+ parallel_mgr = get_parallel_info_manager()
95+ forward_ctx = get_forward_context()
96+ if not parallel_mgr.get(ParallelType.MOE_EP).is_enabled():
97+ return False
98+
99+ if device_type == DeviceType.ASCEND_910B:
100+ # 910B: decode phase only, large cluster required
101+ if forward_ctx.is_prefill or parallel_mgr.world_size < 16:
102+ return False
103+ elif device_type == DeviceType.ASCEND_910_93:
104+ # 910C: decode phase only
105+ if forward_ctx.is_prefill:
106+ return False
107+ # Strict capacity check: fail fast if exceeded
108+ if forward_ctx.batch_descriptor.num_tokens > get_mc2_token_capacity():
109+ error_msg = (
110+ f"MC2 operator limitation: tokens per card ({forward_ctx.batch_descriptor.num_tokens})"
111+ f" exceed the limit of mc2_token_capacity = {get_mc2_token_capacity()}. "
112+ f"Please reduce the batch_size during the decode stage."
113+ )
114+ logger.error(error_msg)
115+ raise ValueError(error_msg)
116+ else:
117+ logger.error("Unsupported device type: {device_type}")
118+ raise RuntimeError("Unsupported device type: {device_type}")
119+
120+ # Incompatible with MoE TP parallelism
121+ if parallel_mgr.get(ParallelType.MOE_TP).is_enabled():
122+ return False
123+ return True
124+
125+ @staticmethod
126+ def get_comm_type() -> MoECommType:
127+ return MoECommType.MC2
128+ 
129+ 
130+class All2AllStrategy(MoECommStrategyBase):
131+ """All2All strategy: fallback for specific scenarios.
132+
133+ 910B: W4A8_DYNAMIC quant or Attn DP enabled.
134+ 910C: prefill phase when fused MC2 unavailable.
135+ """
136+
137+ @staticmethod
138+ def is_applicable(quant_type: Optional[str], max_num_tokens_per_device: Optional[int]) -> bool:
139+ device_type = get_npu_node_info().get_device_type()
140+ parallel_mgr = get_parallel_info_manager()
141+ if not parallel_mgr.get(ParallelType.MOE_EP).is_enabled():
142+ return False
143+
144+ if device_type == DeviceType.ASCEND_910B:
145+ # 910B: prefer W4A8_DYNAMIC; allow fallback if Attn DP enabled
146+ if quant_type != QuantType.W4A8_DYNAMIC:
147+ return parallel_mgr.get(ParallelType.ATTN_DP).is_enabled()
148+
149+ # Compatibility rule: MoE TP + All2All requires special handling
150+ if parallel_mgr.get(ParallelType.MOE_TP).is_enabled():
151+ # Attn DP + MoE TP > 1 is not supported for MC2/All2All
152+ if parallel_mgr.get(ParallelType.ATTN_DP).is_enabled():
153+ err_msg = 'MoECommType.MC2 and MoECommType.ALLTOALL: Do not support moe_tp > 1'
154+ logger.error(err_msg)
155+ raise RuntimeError(err_msg)
156+ return False
157+ return True
158+
159+ @staticmethod
160+ def get_comm_type() -> MoECommType:
161+ return MoECommType.ALLTOALL
162+ 
163+ 
164+class AllGatherStrategy(MoECommStrategyBase):
165+ """AllGather strategy: universal fallback with lowest priority."""
166+
167+ @staticmethod
168+ def is_applicable(quant_type: Optional[str], max_num_tokens_per_device: Optional[int]) -> bool:
169+ # Fallback: applicable when no other strategy matches
170+ return True
171+
172+ @staticmethod
173+ def get_comm_type() -> MoECommType:
174+ return MoECommType.ALLGATHER
175+ 
176+ 
177+# Strategy priority order: first applicable strategy is selected
178+MOE_COMM_STRATEGIES = [
179+ FusedMC2Strategy, # P0: Optimal (910C Fused)
180+ MC2Strategy, # P1: High perf (large cluster/decode)
181+ All2AllStrategy, # P2: Specific quant/prefill
182+ AllGatherStrategy, # P3: Universal fallback
183+]
@@ -1,3 +1,4 @@
1+# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
1# SPDX-License-Identifier: Apache-2.02# SPDX-License-Identifier: Apache-2.0
2# Copyright (c) 2024; NVIDIA CORPORATION. All rights reserved.3# Copyright (c) 2024; NVIDIA CORPORATION. All rights reserved.
3# Copyright (c) 2025 Huawei Technologies Co., Ltd. All Rights Reserved.4# Copyright (c) 2025 Huawei Technologies Co., Ltd. All Rights Reserved.
@@ -596,10 +597,11 @@ class TokenDispatcherWithAll2AllV(Singleton, MoETokenDispatcher):
596 global_input_tokens_local_experts_indices):597 global_input_tokens_local_experts_indices):
597 # Early return if no local experts or no tokens598 # Early return if no local experts or no tokens
598 if num_local_experts <= 1:599 if num_local_experts <= 1:
599- return global_input_tokens, dynamic_scale, None600+ return global_input_tokens, None
600 601 
601 # Handle quantized case602 # Handle quantized case
602 if self.with_quant:603 if self.with_quant:
604+ expert_idx_2d = global_input_tokens_local_experts_indices.unsqueeze(-1)
603 active_num = global_input_tokens_local_experts_indices.numel()605 active_num = global_input_tokens_local_experts_indices.numel()
604 606 
605 # Handle case with no active tokens607 # Handle case with no active tokens
@@ -607,16 +609,21 @@ class TokenDispatcherWithAll2AllV(Singleton, MoETokenDispatcher):
607 reversed_global_input_permutation_mapping = global_input_tokens_local_experts_indices609 reversed_global_input_permutation_mapping = global_input_tokens_local_experts_indices
608 return global_input_tokens, dynamic_scale, reversed_global_input_permutation_mapping610 return global_input_tokens, dynamic_scale, reversed_global_input_permutation_mapping
609 611 
610- dynamic_scale, _ = torch_npu.npu_moe_token_permute(612+ # Process with active tokens
611- dynamic_scale.unsqueeze(-1),613+ (global_input_tokens, reversed_global_input_permutation_mapping,
612- global_input_tokens_local_experts_indices)614+ _, expanded_scale) = torch_npu.npu_moe_init_routing_v2(
613- dynamic_scale = dynamic_scale.squeeze(-1)615+ global_input_tokens,
614- 616+ expert_idx_2d,
615- # Handle non-quantized case617+ scale=dynamic_scale,
616- global_input_tokens, reversed_global_input_permutation_mapping = torch_npu.npu_moe_token_permute(618+ active_num=active_num,
617- global_input_tokens,619+ expert_capacity=0,
618- global_input_tokens_local_experts_indices)620+ expert_num=num_local_experts,
619- return global_input_tokens, dynamic_scale, reversed_global_input_permutation_mapping621+ expert_tokens_num_type=1,
622+ expert_tokens_num_flag=True,
623+ active_expert_range=[0, num_local_experts],
624+ quant_mode=-1,
625+ row_idx_type=0)
626+ return global_input_tokens, expanded_scale, reversed_global_input_permutation_mapping
620 627 
621 # Handle non-quantized case628 # Handle non-quantized case
622 global_input_tokens, reversed_global_input_permutation_mapping = torch_npu.npu_moe_token_permute(629 global_input_tokens, reversed_global_input_permutation_mapping = torch_npu.npu_moe_token_permute(
Mmindie_llm/runtime/layers/quantization/ms_model_slim/w8a8.py+31-58文件内容审核中,请稍后刷新重试
@@ -25,10 +25,10 @@ _MC2_TOKEN_CAPACITY = None
25 25 
26 26 
27def set_mc2_token_capacity(max_num_reqs, uniform_decode_query_len):27def set_mc2_token_capacity(max_num_reqs, uniform_decode_query_len):
28- max_num_tokens = min(max_num_reqs * uniform_decode_query_len, 512)28+ max_num_tokens = max_num_reqs * uniform_decode_query_len
29- tp_size = get_parallel_info_manager().get(ParallelType.MOE_TP).group_size29+ tp_size = get_parallel_info_manager().get(ParallelType.ATTN_TP).group_size
30 # Use integer arithmetic for ceiling division.30 # Use integer arithmetic for ceiling division.
31- num_tokens_per_tp_rank = (max_num_tokens + tp_size - 1) // tp_size31+ num_tokens_per_tp_rank = min((max_num_tokens + tp_size - 1) // tp_size, 512)
32 global _MC2_TOKEN_CAPACITY32 global _MC2_TOKEN_CAPACITY
33 _MC2_TOKEN_CAPACITY = num_tokens_per_tp_rank * tp_size33 _MC2_TOKEN_CAPACITY = num_tokens_per_tp_rank * tp_size
34 34 
@@ -23,7 +23,6 @@ from mindie_llm.runtime.layers.fused_moe.experts_selector import select_experts
23from mindie_llm.runtime.layers.fused_moe.fused_moe import FusedMoE, assign_experts23from mindie_llm.runtime.layers.fused_moe.fused_moe import FusedMoE, assign_experts
24from mindie_llm.runtime.model_runner.forward_context import get_forward_context24from mindie_llm.runtime.model_runner.forward_context import get_forward_context
25from mindie_llm.runtime.utils.distributed import get_parallel_info_manager25from mindie_llm.runtime.utils.distributed import get_parallel_info_manager
26-from mindie_llm.runtime.utils.npu.device_utils import DeviceType, get_npu_node_info
27from mindie_llm.runtime.layers.attention import get_global_attn_dict26from mindie_llm.runtime.layers.attention import get_global_attn_dict
28from mindie_llm.runtime.layers.parameter import BaseParameter27from mindie_llm.runtime.layers.parameter import BaseParameter
29 28 
@@ -131,8 +130,6 @@ class DeepseekV3Moe(nn.Module):
131 self.expert_num = config.n_routed_experts130 self.expert_num = config.n_routed_experts
132 self.expert_list = assign_experts(config.n_routed_experts,131 self.expert_list = assign_experts(config.n_routed_experts,
133 parallel_info.moe_ep.group_size)[parallel_info.moe_ep.rank]132 parallel_info.moe_ep.group_size)[parallel_info.moe_ep.rank]
134- ascend_device_type = get_npu_node_info().get_device_type()
135- self.is_fused_op_enabled = True if ascend_device_type in {DeviceType.ASCEND_910_93} else False
136 self.experts = FusedMoE(133 self.experts = FusedMoE(
137 num_experts=config.n_routed_experts,134 num_experts=config.n_routed_experts,
138 topk_num=self.topk_num,135 topk_num=self.topk_num,
@@ -140,8 +137,7 @@ class DeepseekV3Moe(nn.Module):
140 intermediate_size=config.moe_intermediate_size,137 intermediate_size=config.moe_intermediate_size,
141 quant_config=quant_config,138 quant_config=quant_config,
142 prefix=f"{prefix}.experts",139 prefix=f"{prefix}.experts",
143- suffix=["gate_proj", "down_proj", "up_proj"],140+ suffix=["gate_proj", "down_proj", "up_proj"],)
144- is_fused_op_enabled=self.is_fused_op_enabled)
145 141 
146 self.gate = ReplicatedLinear(142 self.gate = ReplicatedLinear(
147 config.hidden_size,143 config.hidden_size,