Repository navigation
RPC: Improve loading times - #29413
Conversation
7d8a964 to
3428627
Compare
3a95ed3 to
d88ec8c
Compare
ggerganov
left a comment
There was a problem hiding this comment.
Generally, it would help reviewing changes if there is some detailed description in the PR about what is the thought process and what generally the changes achieve.
For example, I've looked at this PR for ~1h and now I understand most of the things, but it definitely took me a while to get there. The dispatcher now has flags with "remote capabilities" called "sever_flags". It also has a new call that allows to do sync send with extra buffer (called "payload") that is not copied into the rpc message structure. It is used for the SET_TENSOR command and it is an exception to how all other RPC messages are handled. There is also some buffer chunking that allegedly speeds up host -> device transfers.
The changes in transport.cpp are not clear to me yet - I don't know what they do and why they are needed.
|
Yeah agreed. The transport changes are for receiving partial messages. The model loader changes are for avoiding a bounce buffer when async uploads are not possible. |
|
Beyond making uploads a bit faster, this also significantly reduces peak memory usage with large models. Uploading Qwen3.8-Flash-Next's 27GB per_layer_token_embd on my setup couldn't be done due to hitting OOM. With my own, shallower implementation: |
e31caf2 to
33bc861
Compare
|
@ggerganov I've added a summary of changes to this PR. I think it's a big improvement over how we're currently doing RPC and it will make non-cached loads (the default) very usable (apart from lowering peak mem usage) |
There was a problem hiding this comment.
I think it would be worth trying to do a from-scratch implementation of ggml-rpc.cpp with an LLM (guided with the existing implementation). Some areas worth improving:
- message serialization
- improve type safety
- better logs and tests
Think such a refactor/reimplementation can improve the development flow in general of this sub-system.
Overview
Improves loading time for me by 5x on 2 sparks.
DeepSeek-V4-Flash (145.6 GiB), 2x DGX Spark, both devices over RPC (RDMA), cold page cache,
load_tensorstime:-sm layer -lm dio-sm tensor -lm dio-sm layer, default (mmap)-sm tensor, default (mmap)Changes:
RPC_SERVER_FLAG_CACHE, set byrpc-server -c). The client hashes tensors forSET_TENSOR_HASHonly when the server has a cache.SET_TENSORsends the tensor data straight from the caller's pointer after the header, instead of first copying it into a zero-filled message buffer.SET_TENSORdata is read in chunks through a reused 16 MiB buffer, instead of a new full-size vector for every tensor. The-ccache-save path still reads the whole tensor so it can hash it.rdma_recvcan read part of a receive slot, so receive sizes no longer have to match send sizes. The chunked receive above needs this.This also lowers peak memory during loading: the client keeps one fewer copy of each tensor, and the server's receive buffer is 16 MiB instead of the size of the tensor. Uploads that go through
SET_TENSOR_2D(-sm tensorsplit weights) are not changed.Additional information
Requirements