Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/engine/community_models/f5_tts/dit_modules.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ std::vector<ConstStage> * const_stage_begin();
void const_stage_bind(std::vector<ConstStage> * stage, ggml_backend_t backend);
void const_stage_upload(std::vector<ConstStage> * stage, ggml_backend_t backend);
void const_stage_end(std::vector<ConstStage> * stage);
// Frees the backend buffers const_stage_bind gave to each staged constant, the
// host copies, and the vector itself. The graph that staged them owns the vector
// from const_stage_begin, so this runs on that graph's destruction: without it
// every CUDA cache eviction leaks the pe table, the masks and the per-block ones
// rows of the evicted graph.
void const_stage_free(std::vector<ConstStage> * stage);
} // namespace engine::models::f5_tts

namespace engine::models::f5_tts {
Expand Down
12 changes: 10 additions & 2 deletions src/community_models/f5_tts/dit_modules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,20 @@ void const_stage_upload(std::vector<ConstStage> * stage, ggml_backend_t backend)
}
}
void const_stage_end(std::vector<ConstStage> * stage) {
// detach only; the vector is deliberately leaked (a few KB per graph
// build) to avoid ownership hazards across build paths.
// detach only; ownership of the staged constants was handed to the graph that
// built them (const_stage_free runs with that graph's destructor).
t_const_stage = nullptr;
(void)stage;
}

void const_stage_free(std::vector<ConstStage> * stage) {
if (stage == nullptr) return;
for (auto & c : *stage) {
if (c.owned_buffer != nullptr) ggml_backend_buffer_free(c.owned_buffer);
}
delete stage;
}


F5DiTGraphBuild build_dit_modules_graph(
ggml_context * ggml,
Expand Down
13 changes: 13 additions & 0 deletions src/community_models/f5_tts/runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,11 @@ std::pair<std::vector<float>, std::vector<float>> f5_dit_forward_cfg(
ggml_tensor * th_t = nullptr; // [256, 1]
ggml_tensor * output = nullptr; // [MEL, N] (half 0, conditioned)
ggml_tensor * out_u = nullptr; // [MEL, N] (half 1, uncond)
// The staged graph constants this build created (pe table, masks,
// per-block ones rows). On CUDA each carries a private backend buffer
// allocated in const_stage_bind: the eviction path destroys the
// unique_ptr, and nothing else frees them.
std::vector<engine::models::f5_tts::ConstStage> * stage = nullptr;
~CfgGraph() {
// Cache eviction (more than two distinct (N, NT) keys in one process,
// i.e. every chunk past the second of a chunked request) destroys the
Expand All @@ -338,6 +343,7 @@ std::pair<std::vector<float>, std::vector<float>> f5_dit_forward_cfg(
if (gallocr != nullptr) ggml_gallocr_free(gallocr);
if (io_buffer != nullptr) ggml_backend_buffer_free(io_buffer);
if (ctx != nullptr) ggml_free(ctx);
const_stage_free(stage);
}
};
static auto * cache = new std::map<std::tuple<const LoadedModel *, int, int>, std::unique_ptr<CfgGraph>>();
Expand Down Expand Up @@ -367,6 +373,7 @@ std::pair<std::vector<float>, std::vector<float>> f5_dit_forward_cfg(
ctx, dit_w, arch, N, NT, model.backend_type);
const_stage_end(stage);
cfg_staged = stage;
gnew->stage = stage;
// Mark I/O explicitly: without ggml_set_input/output the gallocr
// treats leaves as scratch and may clobber them across replays.
ggml_set_input(io.x.tensor);
Expand Down Expand Up @@ -539,12 +546,17 @@ std::vector<float> f5_dit_forward(
ggml_tensor * tap_time_embed = nullptr;
ggml_tensor * tap_block0 = nullptr;
ggml_tensor * tap_block21 = nullptr;
// The staged graph constants this build created (pe table, per-block ones
// rows). On CUDA each carries a private backend buffer from
// const_stage_bind, so the vector has to die with the graph.
std::vector<engine::models::f5_tts::ConstStage> * stage = nullptr;
~DiTGraph() {
// Leaked by design when cached (freed only on program-graph reset);
// destroyed here only when construction throws mid-build.
if (gallocr != nullptr) ggml_gallocr_free(gallocr);
if (io_buffer != nullptr) ggml_backend_buffer_free(io_buffer);
if (ctx != nullptr) ggml_free(ctx);
const_stage_free(stage);
}
};

Expand Down Expand Up @@ -587,6 +599,7 @@ std::vector<float> f5_dit_forward(
const_stage_end(stage);
// staged constants upload after ggml_backend_alloc_ctx_tensors below
staged_module_consts = stage;
gnew->stage = stage;
ggml_set_input(io.x.tensor);
ggml_set_input(io.cond.tensor);
ggml_set_input(io.text_ids.tensor);
Expand Down
Loading