ggml : reduce CPU overhead in meta backend (#22041)
* cache subgraph splits when cgraph is unchanged Skip per-call subgraph construction in ggml_backend_meta_graph_compute when the same ggml_cgraph is used consecutively. Assign uid to every sub-graph so that CUDA's fast uid check path hits too. * Address review comments * Keep the scope as is * Rename last_uid and last_n_subgraphs field. Remove last_max_tmp_size field. Refactor code. * Address review comments * Update ggml/src/ggml-backend-meta.cpp Co-authored-by: Johannes Gäßler <johannesg@5d6.de> * Update ggml/src/ggml-backend-meta.cpp Co-authored-by: Johannes Gäßler <johannesg@5d6.de> --------- Co-authored-by: Johannes Gäßler <johannesg@5d6.de>
This commit is contained in:
co-authored by
Johannes Gäßler
parent
037bfe38d0
commit
bcdcc1044f
@@ -1456,6 +1456,8 @@ struct ggml_backend_meta_context {
|
|||||||
int max_nnodes = 0;
|
int max_nnodes = 0;
|
||||||
size_t max_tmp_size = 0;
|
size_t max_tmp_size = 0;
|
||||||
size_t max_subgraphs = 0;
|
size_t max_subgraphs = 0;
|
||||||
|
size_t n_subgraphs = 0;
|
||||||
|
uint64_t uid = 0;
|
||||||
|
|
||||||
void * comm_ctx = nullptr;
|
void * comm_ctx = nullptr;
|
||||||
ggml_backend_comm_allreduce_tensor_t comm_allreduce = nullptr;
|
ggml_backend_comm_allreduce_tensor_t comm_allreduce = nullptr;
|
||||||
@@ -1616,6 +1618,9 @@ static enum ggml_status ggml_backend_meta_graph_compute(ggml_backend_t backend,
|
|||||||
const size_t n_backends = ggml_backend_meta_n_backends(backend);
|
const size_t n_backends = ggml_backend_meta_n_backends(backend);
|
||||||
ggml_backend_meta_context * backend_ctx = (ggml_backend_meta_context *) backend->context;
|
ggml_backend_meta_context * backend_ctx = (ggml_backend_meta_context *) backend->context;
|
||||||
|
|
||||||
|
// If the previous cgraph had a defined UID it can be used to skip rebuilding the subgraphs per simple backend.
|
||||||
|
const bool needs_rebuild = (cgraph->uid == 0) || (cgraph->uid != backend_ctx->uid);
|
||||||
|
|
||||||
bool max_nnodes_raised = false;
|
bool max_nnodes_raised = false;
|
||||||
if (cgraph->n_nodes > backend_ctx->max_nnodes) {
|
if (cgraph->n_nodes > backend_ctx->max_nnodes) {
|
||||||
for (size_t j = 0; j < n_backends; j++) {
|
for (size_t j = 0; j < n_backends; j++) {
|
||||||
@@ -1625,7 +1630,13 @@ static enum ggml_status ggml_backend_meta_graph_compute(ggml_backend_t backend,
|
|||||||
}
|
}
|
||||||
backend_ctx->max_nnodes = cgraph->n_nodes;
|
backend_ctx->max_nnodes = cgraph->n_nodes;
|
||||||
max_nnodes_raised = true;
|
max_nnodes_raised = true;
|
||||||
|
assert(needs_rebuild);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needs_rebuild) {
|
||||||
|
size_t n_subgraphs = 0;
|
||||||
|
size_t max_tmp_size = 0;
|
||||||
|
|
||||||
for (size_t j = 0; j < n_backends; j++) {
|
for (size_t j = 0; j < n_backends; j++) {
|
||||||
auto & bcj = backend_ctx->backend_configs[j];
|
auto & bcj = backend_ctx->backend_configs[j];
|
||||||
|
|
||||||
@@ -1642,8 +1653,6 @@ static enum ggml_status ggml_backend_meta_graph_compute(ggml_backend_t backend,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t n_subgraphs = 0;
|
|
||||||
size_t max_tmp_size = 0;
|
|
||||||
{
|
{
|
||||||
// For MoE models it may make sense to delay the AllReduce in order to reduce I/O:
|
// For MoE models it may make sense to delay the AllReduce in order to reduce I/O:
|
||||||
auto get_i_delayed = [&](const int i) -> int {
|
auto get_i_delayed = [&](const int i) -> int {
|
||||||
@@ -1739,6 +1748,9 @@ static enum ggml_status ggml_backend_meta_graph_compute(ggml_backend_t backend,
|
|||||||
GGML_ASSERT(i_start == cgraph->n_nodes);
|
GGML_ASSERT(i_start == cgraph->n_nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backend_ctx->uid = cgraph->uid;
|
||||||
|
backend_ctx->n_subgraphs = n_subgraphs;
|
||||||
|
|
||||||
if (max_tmp_size > backend_ctx->max_tmp_size) {
|
if (max_tmp_size > backend_ctx->max_tmp_size) {
|
||||||
for (size_t j = 0; j < n_backends; j++) {
|
for (size_t j = 0; j < n_backends; j++) {
|
||||||
auto & bcj = backend_ctx->backend_configs[j];
|
auto & bcj = backend_ctx->backend_configs[j];
|
||||||
@@ -1747,7 +1759,6 @@ static enum ggml_status ggml_backend_meta_graph_compute(ggml_backend_t backend,
|
|||||||
backend_ctx->max_tmp_size = max_tmp_size;
|
backend_ctx->max_tmp_size = max_tmp_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (max_nnodes_raised || n_subgraphs > backend_ctx->max_subgraphs) {
|
if (max_nnodes_raised || n_subgraphs > backend_ctx->max_subgraphs) {
|
||||||
backend_ctx->max_subgraphs = std::max(backend_ctx->max_subgraphs, n_subgraphs);
|
backend_ctx->max_subgraphs = std::max(backend_ctx->max_subgraphs, n_subgraphs);
|
||||||
const size_t n_reduce_steps = backend_ctx->n_reduce_steps();
|
const size_t n_reduce_steps = backend_ctx->n_reduce_steps();
|
||||||
@@ -1793,6 +1804,8 @@ static enum ggml_status ggml_backend_meta_graph_compute(ggml_backend_t backend,
|
|||||||
const size_t hash_pos_ij = ggml_hash_insert(&cgraph_ij->visited_hash_set, node_ij);
|
const size_t hash_pos_ij = ggml_hash_insert(&cgraph_ij->visited_hash_set, node_ij);
|
||||||
cgraph_ij->use_counts[hash_pos_ij] = cgraph->use_counts[hash_pos_orig];
|
cgraph_ij->use_counts[hash_pos_ij] = cgraph->use_counts[hash_pos_orig];
|
||||||
}
|
}
|
||||||
|
cgraph_ij->uid = ggml_graph_next_uid();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1898,7 +1911,7 @@ static enum ggml_status ggml_backend_meta_graph_compute(ggml_backend_t backend,
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < n_subgraphs; i++) {
|
for (size_t i = 0; i < backend_ctx->n_subgraphs; i++) {
|
||||||
for (size_t j = 0; j < n_backends; j++) {
|
for (size_t j = 0; j < n_backends; j++) {
|
||||||
auto & bcj = backend_ctx->backend_configs[j];
|
auto & bcj = backend_ctx->backend_configs[j];
|
||||||
const ggml_status status = ggml_backend_graph_compute_async(bcj.backend, bcj.cgraphs[i].cgraph_main);
|
const ggml_status status = ggml_backend_graph_compute_async(bcj.backend, bcj.cgraphs[i].cgraph_main);
|
||||||
@@ -1907,7 +1920,7 @@ static enum ggml_status ggml_backend_meta_graph_compute(ggml_backend_t backend,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n_backends > 1 && i < n_subgraphs - 1) {
|
if (n_backends > 1 && i < backend_ctx->n_subgraphs - 1) {
|
||||||
bool backend_allreduce_success = false;
|
bool backend_allreduce_success = false;
|
||||||
if (backend_ctx->comm_ctx) {
|
if (backend_ctx->comm_ctx) {
|
||||||
std::vector<ggml_tensor *> nodes;
|
std::vector<ggml_tensor *> nodes;
|
||||||
|
|||||||
Reference in New Issue
Block a user