Skip to content

Commit 8d984e4

Browse files
[executorch][muse] Add cuda dflash executor (#24039)
This PR was created by the merge bot to help merge the original PR into the main branch. ghstack PR number: #23981 by @Gasoonjia ^ Please use this as the source of truth for the PR details, comments, and reviews ghstack PR base: https://github.com/pytorch/executorch/tree/gh/Gasoonjia/80/base ghstack PR head: https://github.com/pytorch/executorch/tree/gh/Gasoonjia/80/head Merge bot PR base: https://github.com/pytorch/executorch/tree/gh/Gasoonjia/79/orig Merge bot PR head: https://github.com/pytorch/executorch/tree/gh/Gasoonjia/80/orig Differential Revision: [D125705713](https://our.internmc.facebook.com/intern/diff/D125705713/) @diff-train-skip-merge Co-authored-by: gasoonjia <gasoonjia@icloud.com>
1 parent 81b1dc1 commit 8d984e4

10 files changed

Lines changed: 1361 additions & 13 deletions

File tree

‎examples/models/muse-glimmer/BATCHING_SERVING.md‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
The batching runner and multiplexed worker support MLX autoregressive generation
44
with text only or text plus one image across the submitted conversation, and
55
CUDA autoregressive generation with text only. They are opt-in entry points; the
6-
legacy runners and export defaults remain unchanged. DFlash batching is MLX only.
6+
legacy runners and export defaults remain unchanged. DFlash batching runs on MLX
7+
and CUDA (text only).
78
CUDA specifics are in [CUDA](#cuda) below.
89

910
## Export
@@ -227,3 +228,10 @@ snapshots are enabled. Their total reservation must leave one cell for padded
227228
writes within the exported `--max-cells`.
228229
The cell pool tracks at most 64 resident sessions. Prefix snapshots clone a
229230
session's cells by reference, sharing the prompt's KV rather than copying it.
231+
232+
For DFlash, export the tapped target and packed draft with
233+
`export_dflash --backend cuda --use-offgraph-kv-cache` (add `--draft-max-cells`
234+
and `--max-draft-owners`), then add `--dflash` to the serve command above. The
235+
draft ABI and `--dflash-n-draft` behave as on MLX. Drafts are greedy; the target
236+
accepts or resamples them on the device under each request's sampling. Decode
237+
drafts of up to four owners run in CUDA graphs.

‎examples/models/muse-glimmer/CMakeLists.txt‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ if(MUSE_GLIMMER_BUILD_BATCHING OR MUSE_GLIMMER_BUILD_BATCHING_TESTS)
242242

243243
if(MUSE_GLIMMER_BUILD_BATCHING)
244244
if(_batching_backend STREQUAL "cuda")
245-
set(_batching_executor)
245+
set(_batching_executor runtime/cuda_dflash_executor.cpp)
246246
set(_batching_backend_library cuda_batching)
247247
else()
248248
set(_batching_executor runtime/mlx_executor.cpp)
@@ -356,5 +356,24 @@ if(MUSE_GLIMMER_BUILD_BATCHING OR MUSE_GLIMMER_BUILD_BATCHING_TESTS)
356356
extension_llm_serving Threads::Threads
357357
)
358358
add_test(NAME muse_glimmer_batching COMMAND muse_glimmer_batching_test)
359+
if(MUSE_GLIMMER_BUILD_BATCHING AND _batching_backend STREQUAL "cuda")
360+
# Tokenizer include paths contain regex.h; keep GoogleTest and its users
361+
# on the same simple-regex ABI instead of the shadowed POSIX header.
362+
add_subdirectory(
363+
${EXECUTORCH_ROOT}/third-party/googletest
364+
${CMAKE_CURRENT_BINARY_DIR}/dflash_googletest EXCLUDE_FROM_ALL
365+
)
366+
target_compile_definitions(gtest PUBLIC GTEST_HAS_POSIX_RE=0)
367+
add_executable(
368+
muse_glimmer_cuda_dflash_test tests/cuda_dflash_executor_test.cpp
369+
)
370+
target_link_libraries(
371+
muse_glimmer_cuda_dflash_test PRIVATE muse_glimmer_batching_runtime
372+
GTest::gtest_main
373+
)
374+
add_test(NAME muse_glimmer_cuda_dflash
375+
COMMAND muse_glimmer_cuda_dflash_test
376+
)
377+
endif()
359378
endif()
360379
endif()
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
load("@fbcode_macros//build_defs:build_file_migration.bzl", "fbcode_target")
2+
load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "runtime")
3+
4+
oncall("executorch")
5+
6+
fbcode_target(
7+
_kind = runtime.cxx_library,
8+
name = "cuda_dflash_executor",
9+
srcs = ["cuda_dflash_executor.cpp"],
10+
header_namespace = "executorch/examples/models/muse-glimmer/runtime",
11+
exported_headers = [
12+
"backend_factory.h",
13+
"cuda_dflash_executor.h",
14+
"engine/muse_glimmer_vision_runtime.h",
15+
"prompt_preparation.h",
16+
],
17+
visibility = ["PUBLIC"],
18+
deps = [
19+
"//executorch/extension/cuda:caller_stream",
20+
"//executorch/extension/llm/runner:stats",
21+
"//executorch/runtime/backend:interface",
22+
],
23+
exported_deps = [
24+
"fbsource//third-party/nlohmann-json:nlohmann-json",
25+
"//executorch/backends/cuda/batching:cuda_executor",
26+
"//executorch/extension/llm/batching:batching",
27+
"//executorch/extension/llm/batching:executor_utils",
28+
"//executorch/extension/llm/cache:kv_cache",
29+
"//executorch/extension/llm/serving:serving_runtime",
30+
"//executorch/extension/module:module",
31+
"//executorch/extension/tensor:tensor",
32+
],
33+
external_deps = [("cuda", None, "cuda-lazy"), "nlohmann_json"],
34+
)

‎examples/models/muse-glimmer/runtime/backend_factory.cpp‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#endif
1212
#if defined(EXECUTORCH_BUILD_CUDA)
1313
#include <executorch/backends/cuda/batching/cuda_executor.h>
14+
#include <executorch/examples/models/muse-glimmer/runtime/cuda_dflash_executor.h>
1415
#endif
1516

1617
#include <memory>
@@ -32,9 +33,12 @@ runtime::Result<MuseGlimmerBackend> create_muse_glimmer_backend(
3233
InvalidArgument,
3334
"Muse Glimmer CUDA: a session needs room for a prompt and prediction");
3435
ET_CHECK_OR_RETURN_ERROR(
35-
!config.use_dflash && config.dflash_n_draft == 0,
36-
NotSupported,
37-
"Muse Glimmer CUDA: DFlash batching is not supported");
36+
config.use_dflash || config.dflash_n_draft == 0,
37+
InvalidArgument,
38+
"Muse Glimmer CUDA: dflash_n_draft requires DFlash");
39+
if (config.use_dflash) {
40+
return MuseGlimmerCudaDFlashExecutor::create(config);
41+
}
3842
cb::CudaExecutorConfig executor_config;
3943
executor_config.model_path = config.model_path;
4044
if (!config.data_path.empty()) {

0 commit comments

Comments
 (0)