Skip to content

Commit 931ba24

Browse files
authored
Add channel-wise gated delta rule custom op (pytorch#20913)
Differential Revision: D111952369 Pull Request resolved: pytorch#20913
1 parent d6ad8aa commit 931ba24

7 files changed

Lines changed: 852 additions & 0 deletions

File tree

extension/llm/custom_ops/BUCK

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ fbcode_target(_kind = runtime.python_test,
4545
],
4646
deps = [
4747
"//caffe2:torch",
48+
"//executorch/exir:lib",
49+
"//executorch/runtime:runtime",
4850
],
4951
)
5052

extension/llm/custom_ops/custom_ops.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,89 @@ def update_cache_with_indices_meta(
274274
return torch.empty((1,), dtype=value.dtype, device="meta")
275275

276276

277+
def _validate_channelwise_gated_delta_rule_params(
278+
query,
279+
key,
280+
value,
281+
decay,
282+
beta,
283+
initial_state,
284+
):
285+
assert (
286+
query.dim() == 4
287+
), f"Expected query to be 4 dimensional but got {query.dim()} dimensions."
288+
assert (
289+
key.dim() == 4
290+
), f"Expected key to be 4 dimensional but got {key.dim()} dimensions."
291+
assert (
292+
value.dim() == 4
293+
), f"Expected value to be 4 dimensional but got {value.dim()} dimensions."
294+
assert (
295+
decay.dim() == 4
296+
), f"Expected decay to be 4 dimensional but got {decay.dim()} dimensions."
297+
assert (
298+
beta.dim() == 3
299+
), f"Expected beta to be 3 dimensional but got {beta.dim()} dimensions."
300+
assert (
301+
initial_state.dim() == 4
302+
), f"Expected initial_state to be 4 dimensional but got {initial_state.dim()} dimensions."
303+
304+
for name, tensor in {
305+
"query": query,
306+
"key": key,
307+
"value": value,
308+
"decay": decay,
309+
"beta": beta,
310+
"initial_state": initial_state,
311+
}.items():
312+
assert (
313+
tensor.dtype == torch.float32
314+
), f"Expected {name} to be float32 but got {tensor.dtype}"
315+
316+
assert (
317+
query.shape == key.shape
318+
), f"Expected query and key to have matching shapes but got {query.shape} and {key.shape}"
319+
assert (
320+
query.shape == decay.shape
321+
), f"Expected query and decay to have matching shapes but got {query.shape} and {decay.shape}"
322+
assert (
323+
query.shape[:3] == value.shape[:3]
324+
), f"Expected query and value to match in batch/head/sequence dims but got {query.shape} and {value.shape}"
325+
assert (
326+
beta.shape == query.shape[:3]
327+
), f"Expected beta to match query batch/head/sequence dims but got {beta.shape} and {query.shape}"
328+
assert initial_state.shape == (
329+
query.size(0),
330+
query.size(1),
331+
query.size(3),
332+
value.size(3),
333+
), (
334+
"Expected initial_state to have shape "
335+
f"{(query.size(0), query.size(1), query.size(3), value.size(3))} "
336+
f"but got {initial_state.shape}"
337+
)
338+
339+
340+
@impl(custom_ops_lib, "channelwise_gated_delta_rule", "Meta")
341+
def channelwise_gated_delta_rule_meta(
342+
query,
343+
key,
344+
value,
345+
decay,
346+
beta,
347+
initial_state,
348+
):
349+
_validate_channelwise_gated_delta_rule_params(
350+
query,
351+
key,
352+
value,
353+
decay,
354+
beta,
355+
initial_state,
356+
)
357+
return torch.empty_like(value), torch.empty_like(initial_state)
358+
359+
277360
def _validate_quantized_sdpa_params(
278361
query,
279362
key,

0 commit comments

Comments
 (0)