Skip to content

Commit b54a81c

Browse files
committed
Add a persistent Parakeet helper for macOS integrations
Factor the Parakeet transcription logic out of the one-shot runner so host apps can keep the model warm across requests. Build the new helper alongside the runner and document the helper workflow for app integrations. Made-with: Cursor
1 parent 411ede2 commit b54a81c

9 files changed

Lines changed: 1319 additions & 567 deletions

examples/models/parakeet/CMakeLists.txt

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -108,32 +108,49 @@ if(EXECUTORCH_BUILD_VULKAN)
108108
executorch_target_link_options_shared_lib(vulkan_backend)
109109
endif()
110110

111-
add_executable(parakeet_runner main.cpp timestamp_utils.cpp tokenizer_utils.cpp)
112-
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
113-
target_link_options_gc_sections(parakeet_runner)
114-
if(NOT APPLE AND NOT MSVC)
115-
target_link_options(parakeet_runner PRIVATE "LINKER:-s")
116-
endif()
117-
endif()
111+
set(parakeet_shared_sources parakeet_transcriber.cpp timestamp_utils.cpp
112+
tokenizer_utils.cpp
113+
)
118114

119-
# Copy MLX metallib for runtime if MLX delegate is enabled
120-
if(TARGET mlxdelegate)
121-
executorch_target_copy_mlx_metallib(parakeet_runner)
122-
endif()
115+
set(parakeet_common_include_directories
116+
${_common_include_directories} ${EXECUTORCH_ROOT}/third-party/json/include
117+
)
123118

124-
target_include_directories(
125-
parakeet_runner PUBLIC ${_common_include_directories}
119+
add_executable(parakeet_runner main.cpp ${parakeet_shared_sources})
120+
add_executable(
121+
parakeet_helper parakeet_helper.cpp parakeet_helper_protocol.cpp
122+
${parakeet_shared_sources}
126123
)
127-
target_link_libraries(parakeet_runner PUBLIC ${link_libraries})
128-
target_compile_options(parakeet_runner PUBLIC ${_common_compile_options})
124+
125+
foreach(parakeet_target parakeet_runner parakeet_helper)
126+
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
127+
target_link_options_gc_sections(${parakeet_target})
128+
if(NOT APPLE AND NOT MSVC)
129+
target_link_options(${parakeet_target} PRIVATE "LINKER:-s")
130+
endif()
131+
endif()
132+
133+
if(TARGET mlxdelegate)
134+
executorch_target_copy_mlx_metallib(${parakeet_target})
135+
endif()
136+
137+
target_include_directories(
138+
${parakeet_target} PUBLIC ${parakeet_common_include_directories}
139+
)
140+
target_link_libraries(${parakeet_target} PUBLIC ${link_libraries})
141+
target_compile_options(${parakeet_target} PUBLIC ${_common_compile_options})
142+
endforeach()
129143

130144
# On Windows, copy required DLLs to the executable directory
131145
if(MSVC AND EXECUTORCH_BUILD_CUDA)
132-
add_custom_command(
133-
TARGET parakeet_runner
134-
POST_BUILD
135-
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:aoti_cuda_shims>
136-
$<TARGET_FILE_DIR:parakeet_runner>
137-
COMMENT "Copying aoti_cuda_shims.dll to parakeet_runner directory"
138-
)
146+
foreach(parakeet_target parakeet_runner parakeet_helper)
147+
add_custom_command(
148+
TARGET ${parakeet_target}
149+
POST_BUILD
150+
COMMAND
151+
${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:aoti_cuda_shims>
152+
$<TARGET_FILE_DIR:${parakeet_target}>
153+
COMMENT "Copying aoti_cuda_shims.dll to ${parakeet_target} directory"
154+
)
155+
endforeach()
139156
endif()

examples/models/parakeet/CMakePresets.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,42 +89,42 @@
8989
"displayName": "Build Parakeet runner (CPU)",
9090
"configurePreset": "parakeet-cpu",
9191
"configuration": "Release",
92-
"targets": ["parakeet_runner"]
92+
"targets": ["parakeet_runner", "parakeet_helper"]
9393
},
9494
{
9595
"name": "parakeet-cuda",
9696
"displayName": "Build Parakeet runner (CUDA)",
9797
"configurePreset": "parakeet-cuda",
9898
"configuration": "Release",
99-
"targets": ["parakeet_runner"]
99+
"targets": ["parakeet_runner", "parakeet_helper"]
100100
},
101101
{
102102
"name": "parakeet-cuda-debug",
103103
"displayName": "Build Parakeet runner (CUDA, Debug)",
104104
"configurePreset": "parakeet-cuda-debug",
105105
"configuration": "Debug",
106-
"targets": ["parakeet_runner"]
106+
"targets": ["parakeet_runner", "parakeet_helper"]
107107
},
108108
{
109109
"name": "parakeet-metal",
110110
"displayName": "Build Parakeet runner (Metal)",
111111
"configurePreset": "parakeet-metal",
112112
"configuration": "Release",
113-
"targets": ["parakeet_runner"]
113+
"targets": ["parakeet_runner", "parakeet_helper"]
114114
},
115115
{
116116
"name": "parakeet-mlx",
117117
"displayName": "Build Parakeet runner (MLX)",
118118
"configurePreset": "parakeet-mlx",
119119
"configuration": "Release",
120-
"targets": ["parakeet_runner"]
120+
"targets": ["parakeet_runner", "parakeet_helper"]
121121
},
122122
{
123123
"name": "parakeet-vulkan",
124124
"displayName": "Build Parakeet runner (Vulkan)",
125125
"configurePreset": "parakeet-vulkan",
126126
"configuration": "Release",
127-
"targets": ["parakeet_runner"]
127+
"targets": ["parakeet_runner", "parakeet_helper"]
128128
}
129129
],
130130
"workflowPresets": [

examples/models/parakeet/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ make parakeet-cuda
224224
make parakeet-mlx
225225
```
226226

227+
Each Parakeet build now produces both:
228+
229+
- `parakeet_runner` for one-shot CLI transcription from an audio file
230+
- `parakeet_helper` for long-lived host integrations that keep the model warm and stream PCM requests over stdin/stdout
231+
227232
On Windows (PowerShell), use CMake workflow presets directly:
228233

229234
```powershell
@@ -286,6 +291,26 @@ If your generator is single-config, the runner may be at `.\cmake-out\examples\m
286291
| `--data_path` | Path to data file (.ptd) for delegate data (required for CUDA/CUDA-Windows) |
287292
| `--timestamps` | Timestamp output mode: `none\|token\|word\|segment\|all` (default: `segment`) |
288293

294+
### Persistent Helper
295+
296+
The helper binary uses the same Parakeet transcription stack as `parakeet_runner`,
297+
but keeps the model loaded across multiple requests so host apps can avoid repeated
298+
startup and model load overhead.
299+
300+
Example:
301+
302+
```bash
303+
# Metal
304+
DYLD_LIBRARY_PATH=/usr/lib ./cmake-out/examples/models/parakeet/parakeet_helper \
305+
--model_path examples/models/parakeet/parakeet_metal/model.pte \
306+
--tokenizer_path examples/models/parakeet/parakeet_metal/tokenizer.model
307+
```
308+
309+
The helper accepts framed requests over stdin, validates 16 kHz mono float32 PCM
310+
payloads, and returns status/result messages over stdout. It is intended for app
311+
integrations such as the macOS `ExecuWhisper` frontend in the separate
312+
`executorch-examples` repository.
313+
289314
### Mobile App
290315

291316
Check out a [demo Android app](https://github.com/meta-pytorch/executorch-examples/tree/main/parakeet/android/ParakeetApp) for Parakeet in the separate `executorch-examples` repository.

0 commit comments

Comments
 (0)