diff --git a/mooncake_trace.jsonl b/FAST25-release/arxiv-trace/mooncake_trace.jsonl similarity index 100% rename from mooncake_trace.jsonl rename to FAST25-release/arxiv-trace/mooncake_trace.jsonl diff --git a/Mooncake-v3.pdf b/Mooncake-v3.pdf deleted file mode 100644 index 45fd1401..00000000 Binary files a/Mooncake-v3.pdf and /dev/null differ diff --git a/docs/source/design/transfer-engine.md b/docs/source/design/transfer-engine.md index d25c16b6..87f7a04f 100644 --- a/docs/source/design/transfer-engine.md +++ b/docs/source/design/transfer-engine.md @@ -404,6 +404,7 @@ The general form is `[proto]://[hostname:port]`. For example, the following meta Reclaims all allocated resources and also deletes the global meta data server information. ## Using Transfer Engine to Your Projects + ### Using C/C++ Interface After compiling Mooncake Store, you can move the compiled static library file `libtransfer_engine.a` and the C header file `transfer_engine_c.h` into your own project. There is no need to reference other files under `src/transfer_engine`. diff --git a/docs/source/getting_started/build.md b/docs/source/getting_started/build.md index f30e31b3..e58cd4f2 100644 --- a/docs/source/getting_started/build.md +++ b/docs/source/getting_started/build.md @@ -2,6 +2,15 @@ This document describes how to build Mooncake. +## PyPI Package +Install the Mooncake Transfer Engine package from PyPI, which includes both Mooncake Transfer Engine and Mooncake Store Python bindings: + +```bash +pip install mooncake-transfer-engine==0.3.5 +``` + +📦 **Package Details**: [https://pypi.org/project/mooncake-transfer-engine/](https://pypi.org/project/mooncake-transfer-engine/) + ## Automatic ### Recommended Version diff --git a/docs/source/getting_started/examples/lmcache-integration.md b/docs/source/getting_started/examples/lmcache-integration.md index 4360312d..7dbcef46 100644 --- a/docs/source/getting_started/examples/lmcache-integration.md +++ b/docs/source/getting_started/examples/lmcache-integration.md @@ -17,7 +17,13 @@ LMCache is an open-source Knowledge Delivery Network (KDN), specifically designe This strategic alliance delivers substantial mutual technological advancements: * **LMCache Integrates Mooncake for Enhanced Performance**: LMCache leverages Mooncake’s advanced transfer engine and KVCache storage solutions, significantly enhancing data distribution efficiency and overall system performance. -* **Mooncake Integrates LMCache for Enhanced Functionality**: Mooncake now includes LMCache as its KVCache management layer, benefiting from LMCache’s flexible cache control mechanisms and future-oriented functionalities, such as CacheBlend. This integration enables Mooncake to offer more sophisticated features and improved operational flexibility. +* **Mooncake Integrates LMCache for Enhanced Functionality**: Mooncake now includes LMCache as its KVCache management layer, benefiting from LMCache's flexible cache control mechanisms and future-oriented functionalities, such as CacheBlend. This integration enables Mooncake to offer more sophisticated features and improved operational flexibility. + +## Getting Started + +For a complete deployment guide with step-by-step instructions, see: + +👉 **[vLLM V1 Disaggregated Serving with Mooncake Store and LMCache](vllm-integration/vllmv1-lmcache-integration.md)** ## Performance Benchmarking and Results diff --git a/docs/source/getting_started/examples/vllm-integration/index.md b/docs/source/getting_started/examples/vllm-integration/index.md new file mode 100644 index 00000000..1948326a --- /dev/null +++ b/docs/source/getting_started/examples/vllm-integration/index.md @@ -0,0 +1,11 @@ +# vLLM Disaggregated Serving + +::::{toctree} +:maxdepth: 1 + +vllmv1-lmcache-integration +vllm-integration-v0.2 +vllm-integration-v1 +:::: + + diff --git a/docs/source/getting_started/examples/vllm-integration-v0.2.md b/docs/source/getting_started/examples/vllm-integration/vllm-integration-v0.2.md similarity index 96% rename from docs/source/getting_started/examples/vllm-integration-v0.2.md rename to docs/source/getting_started/examples/vllm-integration/vllm-integration-v0.2.md index 70858af9..d5a6793c 100644 --- a/docs/source/getting_started/examples/vllm-integration-v0.2.md +++ b/docs/source/getting_started/examples/vllm-integration/vllm-integration-v0.2.md @@ -1,13 +1,16 @@ -# vLLM Disaggregated Serving Demo +# vLLM V0 Disaggregated Serving Demo ## Overview -This is the latest version of mooncake-transfer-engine integration doc with the vLLM project based on [PR 10502](https://github.com/vllm-project/vllm/pull/10502) and [PR 10884](https://github.com/vllm-project/vllm/pull/10884) (vllm version: v0.6.4.post1/main) to accelerate KVCache transfer for inter-node disaggregated serving scenario. We have run some experiments to obtain some [preview benchmark results](vllm-benchmark-results-v0.2.md). More benchmark results will be released in due time. +This is the latest version of mooncake-transfer-engine integration doc with the vLLM project based on [PR 10502](https://github.com/vllm-project/vllm/pull/10502) and [PR 10884](https://github.com/vllm-project/vllm/pull/10884) (vllm version: v0.6.4.post1/main) to accelerate KVCache transfer for inter-node disaggregated serving scenario. We have run some experiments to obtain some [preview benchmark results](../../../performance/vllm-benchmark-results-v0.2.md). More benchmark results will be released in due time. **_Please note that this is still an experimental version and will be modified anytime based on feedback from the vLLM community._** - **Update(Apr 10, 2025)**: We are working on the vLLM v1 integration now. Stay tuned. + - **Update(Sep 5, 2025)**: We have released the vLLM v1 integration with Mooncake Store and LMCache. Please refer to [vllmv1-lmcache-integration](vllmv1-lmcache-integration.md) for more details. ## Installation + ### Prerequisite + ```bash pip3 install mooncake-transfer-engine ``` diff --git a/docs/source/getting_started/examples/vllm-integration-v1.md b/docs/source/getting_started/examples/vllm-integration/vllm-integration-v1.md similarity index 97% rename from docs/source/getting_started/examples/vllm-integration-v1.md rename to docs/source/getting_started/examples/vllm-integration/vllm-integration-v1.md index ba558ed2..4aa3e7d9 100644 --- a/docs/source/getting_started/examples/vllm-integration-v1.md +++ b/docs/source/getting_started/examples/vllm-integration/vllm-integration-v1.md @@ -1,4 +1,4 @@ -# vLLM Disaggregated Serving with MooncakeStore +# vLLM V0 Disaggregated Serving with MooncakeStore ## Overview This is the latest version of the MooncakeStore integration doc with the vLLM project based on [PR 10502](https://github.com/vllm-project/vllm/pull/10502) and [PR 12957](https://github.com/vllm-project/vllm/pull/12957) to support KVCache transfer for intra-node and inter-node disaggregated serving scenario. Benchmark results will be released soon. @@ -13,9 +13,12 @@ Main changes from v0.x to v1: **_Please note that this is still an experimental version and will be modified anytime based on feedback from the vLLM community._** - **Update(Apr 10, 2025)**: We are working on the vLLM v1 integration now. Stay tuned. + - **Update(Sep 5, 2025)**: We have released the vLLM v1 integration with Mooncake Store and LMCache. Please refer to [vllmv1-lmcache-integration](vllmv1-lmcache-integration.md) for more details. ## Installation + ### Prerequisite + ```bash pip3 install mooncake-transfer-engine ``` diff --git a/docs/source/getting_started/examples/vllm-integration/vllmv1-lmcache-integration.md b/docs/source/getting_started/examples/vllm-integration/vllmv1-lmcache-integration.md new file mode 100644 index 00000000..0aa0d7f0 --- /dev/null +++ b/docs/source/getting_started/examples/vllm-integration/vllmv1-lmcache-integration.md @@ -0,0 +1,117 @@ +# vLLM V1 Disaggregated Serving with Mooncake Store and LMCache + +## Overview + +The vLLM v1 version has been released with support for PD disaggregation. The detailed design document can be found [here](https://docs.google.com/document/d/1uPGdbEXksKXeN4Q9nUm9hzotqEjQhYmnpAhidLuAsjk). LMCache immediately implemented the corresponding connector to support storage, transmission, and loading of KVCache, enabling collaborative operation with PD nodes. Mooncake, as LMCache's backend storage engine, has undergone extensive optimizations in usability, performance, and stability. This document explains how to deploy a PD disaggregated serving demo using LMCache + Mooncake. + +## Deployment + +1. First, you need to prepare two GPU-equipped machines, which we will refer to as Machine A and Machine B. Install [vLLM](https://docs.vllm.ai/en/latest/getting_started/quickstart.html), [Mooncake](https://kvcache-ai.github.io/Mooncake/getting_started/build.html) and [LMCache](https://docs.lmcache.ai/getting_started/installation.html) on both Machine A and Machine B. For specific installation instructions, please refer to the official documentation of each repository. + +2. Start the Mooncake Master node on Machine A: +```bash +mooncake_master -port 50052 -max_threads 64 -metrics_port 9004 +``` + +3. Start the HTTP metadata server (default port 8080) on Machine A for transfer engine metadata: +```bash +mooncake_http_metadata_server +``` + +4. Launch the Decoder instance on machine A +- Modify the vllm/examples/others/lmcache/disagg_prefill_lmcache_v1/disagg_vllm_launcher.sh file. +```diff +diff --git a/examples/lmcache/disagg_prefill_lmcache_v1/disagg_vllm_launcher.sh b/examples/lmcache/disagg_prefill_lmcache_v1/disagg_vllm_launcher.sh +index 831ef0bb5..a2ff0744c 100644 +--- a/examples/lmcache/disagg_prefill_lmcache_v1/disagg_vllm_launcher.sh ++++ b/examples/lmcache/disagg_prefill_lmcache_v1/disagg_vllm_launcher.sh + elif [[ $1 == "decoder" ]]; then + # Decoder listens on port 8200 +- decode_config_file=$SCRIPT_DIR/configs/lmcache-decoder-config.yaml ++ decode_config_file=$SCRIPT_DIR/configs/mooncake-decoder-config.yaml + + UCX_TLS=cuda_ipc,cuda_copy,tcp \ + LMCACHE_CONFIG_FILE=$decode_config_file \ + LMCACHE_USE_EXPERIMENTAL=True \ + VLLM_ENABLE_V1_MULTIPROCESSING=1 \ + VLLM_WORKER_MULTIPROC_METHOD=spawn \ + CUDA_VISIBLE_DEVICES=1 \ +``` +- Add the `mooncake-decoder-config.yaml` file +```yaml +chunk_size: 256 +remote_url: "mooncakestore://{IP of Machine A}:50052/" +remote_serde: "naive" +local_cpu: False +max_local_cpu_size: 100 + +extra_config: + local_hostname: "{IP of Machine A}" + metadata_server: "http://{IP of Machine A}:8080/metadata" + protocol: "rdma" + device_name: "mlx5_0" # Multiple RDMA devices can be specified as comma-separated list + master_server_address: "{IP of Machine A}:50052" + global_segment_size: 32212254720 # 30GB + local_buffer_size: 1073741824 # 1GB + transfer_timeout: 1 + save_chunk_meta: False +``` + +- Launch the Decoder instance using command +```bash +bash disagg_vllm_launcher.sh decoder Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 +``` + +5. Launch the Prefiller instance on machine B +- Modify the vllm/examples/others/lmcache/disagg_prefill_lmcache_v1/disagg_vllm_launcher.sh file. +```diff +diff --git a/examples/lmcache/disagg_prefill_lmcache_v1/disagg_vllm_launcher.sh b/examples/lmcache/disagg_prefill_lmcache_v1/disagg_vllm_launcher.sh +index 831ef0bb5..9e5a3f044 100644 +--- a/examples/lmcache/disagg_prefill_lmcache_v1/disagg_vllm_launcher.sh ++++ b/examples/lmcache/disagg_prefill_lmcache_v1/disagg_vllm_launcher.sh +@@ -18,12 +18,14 @@ fi + + if [[ $1 == "prefiller" ]]; then + # Prefiller listens on port 8100 +- prefill_config_file=$SCRIPT_DIR/configs/lmcache-prefiller-config.yaml ++ prefill_config_file=$SCRIPT_DIR/configs/mooncake-prefiller-config.yaml +``` + +- Add the `mooncake-prefiller-config.yaml` file +```yaml +chunk_size: 256 +remote_url: "mooncakestore://{IP of Machine A}:50052/" +remote_serde: "naive" +local_cpu: False +max_local_cpu_size: 100 + +extra_config: + local_hostname: "{IP of Machine B}" + metadata_server: "http://{IP of Machine A}:8080/metadata" + protocol: "rdma" + device_name: "mlx5_0" # Multiple RDMA devices can be specified as comma-separated list + master_server_address: "{IP of Machine A}:50052" + global_segment_size: 32212254720 # 30GB + local_buffer_size: 1073741824 # 1GB + transfer_timeout: 1 + save_chunk_meta: False +``` + +- Launch the Prefiller instance using command +```bash +bash disagg_vllm_launcher.sh prefiller Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4 +``` + +6. Launch the `disagg_proxy_server` using command + +```bash +python3 disagg_proxy_server.py --host localhost --port 9000 --prefiller-host IP_of_Machine_B --prefiller-port 8100 --decoder-host IP_of_Machine_A --decoder-port 8200 +``` + +7. Now we can send the requests to the `disagg_proxy_server` to test PD disaggregated serving. + +## Additional Resources + +* [Mooncake x LMCache: Unite to Pioneer KVCache-Centric LLM Serving System](../../../getting_started/examples/lmcache-integration.md) +* [Using Mooncake in LMCache](https://docs.lmcache.ai/kv_cache/storage_backends/mooncake.html) +* [Using LMCache in vLLM](https://github.com/vllm-project/vllm/tree/main/examples/others/lmcache) \ No newline at end of file diff --git a/docs/source/getting_started/quick-start.md b/docs/source/getting_started/quick-start.md new file mode 100644 index 00000000..ce7369ff --- /dev/null +++ b/docs/source/getting_started/quick-start.md @@ -0,0 +1,219 @@ +# Quick Start + +This document describes how to quickly start using Mooncake Transfer Engine and Mooncake Store. + +## Installation + +Install the Mooncake Transfer Engine package from PyPI, which includes both Mooncake Transfer Engine and Mooncake Store Python bindings: + +```bash +pip install mooncake-transfer-engine==0.3.5 +``` + +📦 **Package Details**: [https://pypi.org/project/mooncake-transfer-engine/](https://pypi.org/project/mooncake-transfer-engine/) + +## Transfer Engine Quick Start + +### Start Transfer Engine Receiver (Server) + +```python +import numpy as np +import zmq +from mooncake.engine import TransferEngine + +def main(): + # Initialize ZMQ context and socket + context = zmq.Context() + socket = context.socket(zmq.PUSH) + socket.bind("tcp://*:5555") # Bind to port 5555 for buffer info + + HOSTNAME = "localhost" # localhost for simple demo + METADATA_SERVER = "P2PHANDSHAKE" # [ETCD_SERVER_URL, P2PHANDSHAKE, ...] + PROTOCOL = "tcp" # [rdma, tcp, ...] + DEVICE_NAME = "" # auto discovery if empty + + # Initialize server engine + server_engine = TransferEngine() + server_engine.initialize( + HOSTNAME, + METADATA_SERVER, + PROTOCOL, + DEVICE_NAME + ) + session_id = f"{HOSTNAME}:{server_engine.get_rpc_port()}" + + # Allocate memory on server side (1MB buffer) + server_buffer = np.zeros(1024 * 1024, dtype=np.uint8) + server_ptr = server_buffer.ctypes.data + server_len = server_buffer.nbytes + + # Register memory with Mooncake + ret_value = server_engine.register_memory(server_ptr, server_len) + if ret_value != 0: + print("Mooncake memory registration failed.") + raise RuntimeError("Mooncake memory registration failed.") + + print(f"Server initialized with session ID: {session_id}") + print(f"Server buffer address: {server_ptr}, length: {server_len}") + + # Send buffer info to client + buffer_info = { + "session_id": session_id, + "ptr": server_ptr, + "len": server_len + } + socket.send_json(buffer_info) + print("Buffer information sent to client") + + # Keep server running + try: + while True: + input("Press Ctrl+C to exit...") + except KeyboardInterrupt: + print("\nShutting down server...") + finally: + # Cleanup + ret_value = server_engine.unregister_memory(server_ptr) + if ret_value != 0: + print("Mooncake memory deregistration failed.") + raise RuntimeError("Mooncake memory deregistration failed.") + + socket.close() + context.term() + +if __name__ == "__main__": + main() +``` + +### Start Transfer Engine Sender (Client) + +```python + +import numpy as np +import zmq +from mooncake.engine import TransferEngine + +def main(): + # Initialize ZMQ context and socket + context = zmq.Context() + socket = context.socket(zmq.PULL) + socket.connect(f"tcp://localhost:5555") + + # Wait for buffer info from server + print("Waiting for server buffer information...") + buffer_info = socket.recv_json() + server_session_id = buffer_info["session_id"] + server_ptr = buffer_info["ptr"] + server_len = buffer_info["len"] + print(f"Received server info - Session ID: {server_session_id}") + print(f"Server buffer address: {server_ptr}, length: {server_len}") + + # Initialize client engine + HOSTNAME = "localhost" # localhost for simple demo + METADATA_SERVER = "P2PHANDSHAKE" # [ETCD_SERVER_URL, P2PHANDSHAKE, ...] + PROTOCOL = "tcp" # [rdma, tcp, ...] + DEVICE_NAME = "" # auto discovery if empty + + client_engine = TransferEngine() + client_engine.initialize( + HOSTNAME, + METADATA_SERVER, + PROTOCOL, + DEVICE_NAME + ) + session_id = f"{HOSTNAME}:{client_engine.get_rpc_port()}" + + # Allocate and initialize client buffer (1MB) + client_buffer = np.ones(1024 * 1024, dtype=np.uint8) # Fill with ones + client_ptr = client_buffer.ctypes.data + client_len = client_buffer.nbytes + + # Register memory with Mooncake + ret_value = client_engine.register_memory(client_ptr, client_len) + if ret_value != 0: + print("Mooncake memory registration failed.") + raise RuntimeError("Mooncake memory registration failed.") + + print(f"Client initialized with session ID: {session_id}") + + # Transfer data from client to server + print("Transferring data to server...") + for _ in range(10): + ret = client_engine.transfer_sync_write( + server_session_id, + client_ptr, + server_ptr, + min(client_len, server_len) # Transfer minimum of both lengths + ) + + if ret >= 0: + print("Transfer successful!") + else: + print("Transfer failed!") + + # Cleanup + ret_value = client_engine.unregister_memory(client_ptr) + if ret_value != 0: + print("Mooncake memory deregistration failed.") + raise RuntimeError("Mooncake memory deregistration failed.") + + socket.close() + context.term() + +if __name__ == "__main__": + main() +``` + +### More Examples and Documentation + +Please refer to the [Transfer Engine Python API](../python-api-reference/transfer-engine.md) and [Transfer Engine](../design/transfer-engine.md) for more examples and documentation. + +## Mooncake Store Quick Start + +### Start Mooncake Store + +Before using the store, start the master and metadata services, which are included in the `mooncake-transfer-engine` package: + +```bash +# Start master service (default port 50051) +mooncake_master +``` +Start the HTTP metadata server (default port 8080) for transfer engine metadata: +```bash +# Start HTTP metadata server (default port 8080) +mooncake_http_metadata_server +``` + +### Hello World Example + +```python +from mooncake.store import MooncakeDistributedStore + +# 1. Create store instance +store = MooncakeDistributedStore() + +# 2. Setup with all required parameters +store.setup( + "localhost:12345", # Your node's address + "http://localhost:8080/metadata", # HTTP metadata server + 512*1024*1024, # 512MB segment size + 128*1024*1024, # 128MB local buffer + "tcp", # Use TCP (RDMA for high performance) + "", # Empty for TCP, specify device for RDMA + "localhost:50051" # Master service +) + +# 3. Store data +store.put("hello_key", b"Hello, Mooncake Store!") + +# 4. Retrieve data +data = store.get("hello_key") +print(data.decode()) # Output: Hello, Mooncake Store! + +# 5. Clean up +store.close() +``` + +### More Examples and Documentation + +Please refer to the [Mooncake Store Python API](../python-api-reference/mooncake-store.md) and [Mooncake Store](../design/mooncake-store-preview.md) for more examples and documentation. \ No newline at end of file diff --git a/docs/source/index.md b/docs/source/index.md index 93bf540d..373d788a 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -50,11 +50,11 @@ This repository also hosts its technical report and the open sourced traces. :maxdepth: 2 getting_started/build +getting_started/quick-start getting_started/examples/lmcache-integration getting_started/examples/lmdeploy-integration-v0.9 getting_started/examples/sglang-integration-v1 -getting_started/examples/vllm-integration-v0.2 -getting_started/examples/vllm-integration-v1 +getting_started/examples/vllm-integration/index ::: % Making the most out of Mooncake @@ -72,10 +72,11 @@ performance/allocator_benchmark_result.md % API Documentation :::{toctree} -:caption: Mooncake Store API +:caption: Python API Reference :maxdepth: 1 -mooncake-store-api/python-binding +python-api-reference/mooncake-store +python-api-reference/transfer-engine ::: % Explanation of Mooncake internals diff --git a/docs/source/performance/sglang-benchmark-results-v1.md b/docs/source/performance/sglang-benchmark-results-v1.md index 49676810..66614c60 100644 --- a/docs/source/performance/sglang-benchmark-results-v1.md +++ b/docs/source/performance/sglang-benchmark-results-v1.md @@ -1,4 +1,4 @@ -## PD Disaggregation Performance +# PD Disaggregation Performance We evaluated the current implementation on two A10 servers. By comparing the performance of a 1P1D configuration with that of two regular (non-disaggregated) instances, we observed that P/D disaggregation achieves approximately 30% lower ITL while maintaining comparable total throughput. This aligns with findings from the Mooncake paper, which highlighted that P/D disaggregation is effective in reducing TBT/ITL under similar throughput conditions—or conversely, in enabling higher throughput under stricter ITL/TBT SLOs. Moreover, we anticipate even greater benefits in larger-scale clusters where both the number of prefill and decode nodes (x and y in xPyD configurations) increase, offering enhanced scheduling flexibility and resource efficiency. diff --git a/docs/source/mooncake-store-api/python-binding.md b/docs/source/python-api-reference/mooncake-store.md similarity index 99% rename from docs/source/mooncake-store-api/python-binding.md rename to docs/source/python-api-reference/mooncake-store.md index 43a5750f..29db2904 100644 --- a/docs/source/mooncake-store-api/python-binding.md +++ b/docs/source/python-api-reference/mooncake-store.md @@ -21,6 +21,7 @@ The following services need to be started separately: ## Quick Start ### Start Required Services + Before using the store, start the master and metadata services: ```bash diff --git a/docs/source/python-api-reference/transfer-engine.md b/docs/source/python-api-reference/transfer-engine.md new file mode 100644 index 00000000..5acb89fd --- /dev/null +++ b/docs/source/python-api-reference/transfer-engine.md @@ -0,0 +1,588 @@ +# Transfer Engine Python API + +## Overview + +The Transfer Engine Python API provides a high-level interface for efficient data transfer between distributed systems using RDMA (Remote Direct Memory Access) and other transport protocols. It enables fast, low-latency data movement between nodes in a cluster. + +For interfaces beyond the Python API (C/C++, Golang, Rust), see [Transfer Engine](../design/transfer-engine.md#using-transfer-engine-to-your-projects). + +## Installation + +Install the Mooncake Transfer Engine package from PyPI, which includes both Mooncake Transfer Engine and Mooncake Store Python bindings: + +```bash +pip install mooncake-transfer-engine +``` + +📦 **Package Details**: [https://pypi.org/project/mooncake-transfer-engine/](https://pypi.org/project/mooncake-transfer-engine/) + +## Quick Start + +### Start Transfer Engine Receiver (Server) + +```python +import numpy as np +import zmq +from mooncake.engine import TransferEngine + +def main(): + # Initialize ZMQ context and socket + context = zmq.Context() + socket = context.socket(zmq.PUSH) + socket.bind("tcp://*:5555") # Bind to port 5555 for buffer info + + HOSTNAME = "localhost" # localhost for simple demo + METADATA_SERVER = "P2PHANDSHAKE" # [ETCD_SERVER_URL, P2PHANDSHAKE, ...] + PROTOCOL = "tcp" # [rdma, tcp, ...] + DEVICE_NAME = "" # auto discovery if empty + + # Initialize server engine + server_engine = TransferEngine() + server_engine.initialize( + HOSTNAME, + METADATA_SERVER, + PROTOCOL, + DEVICE_NAME + ) + session_id = f"{HOSTNAME}:{server_engine.get_rpc_port()}" + + # Allocate memory on server side (1MB buffer) + server_buffer = np.zeros(1024 * 1024, dtype=np.uint8) + server_ptr = server_buffer.ctypes.data + server_len = server_buffer.nbytes + + # Register memory with Mooncake + ret_value = server_engine.register_memory(server_ptr, server_len) + if ret_value != 0: + print("Mooncake memory registration failed.") + raise RuntimeError("Mooncake memory registration failed.") + + print(f"Server initialized with session ID: {session_id}") + print(f"Server buffer address: {server_ptr}, length: {server_len}") + + # Send buffer info to client + buffer_info = { + "session_id": session_id, + "ptr": server_ptr, + "len": server_len + } + socket.send_json(buffer_info) + print("Buffer information sent to client") + + # Keep server running + try: + while True: + input("Press Ctrl+C to exit...") + except KeyboardInterrupt: + print("\nShutting down server...") + finally: + # Cleanup + ret_value = server_engine.unregister_memory(server_ptr) + if ret_value != 0: + print("Mooncake memory deregistration failed.") + raise RuntimeError("Mooncake memory deregistration failed.") + + socket.close() + context.term() + +if __name__ == "__main__": + main() +``` + +### Start Transfer Engine Sender (Client) + +```python + +import numpy as np +import zmq +from mooncake.engine import TransferEngine + +def main(): + # Initialize ZMQ context and socket + context = zmq.Context() + socket = context.socket(zmq.PULL) + socket.connect(f"tcp://localhost:5555") + + # Wait for buffer info from server + print("Waiting for server buffer information...") + buffer_info = socket.recv_json() + server_session_id = buffer_info["session_id"] + server_ptr = buffer_info["ptr"] + server_len = buffer_info["len"] + print(f"Received server info - Session ID: {server_session_id}") + print(f"Server buffer address: {server_ptr}, length: {server_len}") + + # Initialize client engine + HOSTNAME = "localhost" # localhost for simple demo + METADATA_SERVER = "P2PHANDSHAKE" # [ETCD_SERVER_URL, P2PHANDSHAKE, ...] + PROTOCOL = "tcp" # [rdma, tcp, ...] + DEVICE_NAME = "" # auto discovery if empty + + client_engine = TransferEngine() + client_engine.initialize( + HOSTNAME, + METADATA_SERVER, + PROTOCOL, + DEVICE_NAME + ) + session_id = f"{HOSTNAME}:{client_engine.get_rpc_port()}" + + # Allocate and initialize client buffer (1MB) + client_buffer = np.ones(1024 * 1024, dtype=np.uint8) # Fill with ones + client_ptr = client_buffer.ctypes.data + client_len = client_buffer.nbytes + + # Register memory with Mooncake + ret_value = client_engine.register_memory(client_ptr, client_len) + if ret_value != 0: + print("Mooncake memory registration failed.") + raise RuntimeError("Mooncake memory registration failed.") + + print(f"Client initialized with session ID: {session_id}") + + # Transfer data from client to server + print("Transferring data to server...") + for _ in range(10): + ret = client_engine.transfer_sync_write( + server_session_id, + client_ptr, + server_ptr, + min(client_len, server_len) # Transfer minimum of both lengths + ) + + if ret >= 0: + print("Transfer successful!") + else: + print("Transfer failed!") + + # Cleanup + ret_value = client_engine.unregister_memory(client_ptr) + if ret_value != 0: + print("Mooncake memory deregistration failed.") + raise RuntimeError("Mooncake memory deregistration failed.") + + socket.close() + context.term() + +if __name__ == "__main__": + main() +``` + +## API Reference + +### Class: TransferEngine + +The main class that provides all transfer engine functionality. + +### Constructor + +```python +TransferEngine() +``` + +Creates a new TransferEngine instance with default settings. + +### Initialization Methods + +#### initialize() + +```python +initialize(local_hostname, metadata_server, protocol, device_name) +``` + +Initializes the transfer engine with basic configuration. + +**Parameters:** +- `local_hostname` (str): The hostname and port of the local server (e.g., "127.0.0.1:12345") +- `metadata_server` (str): The metadata server connection string (e.g., "127.0.0.1:2379" or "etcd://127.0.0.1:2379") +- `protocol` (str): The transport protocol to use ("rdma", "tcp", etc.) +- `device_name` (str): Comma-separated list of device names to filter, or empty string for all devices + +**Returns:** +- `int`: 0 on success, negative value on failure + +#### initialize_ext() + +```python +initialize_ext(local_hostname, metadata_server, protocol, device_name, metadata_type) +``` + +Initializes the transfer engine with extended configuration including metadata type specification. + +**Parameters:** +- `local_hostname` (str): The hostname and port of the local server +- `metadata_server` (str): The metadata server connection string +- `protocol` (str): The transport protocol to use +- `device_name` (str): Comma-separated list of device names to filter +- `metadata_type` (str): The type of metadata server ("etcd", "p2p", etc.) + +**Returns:** +- `int`: 0 on success, negative value on failure + +### Network Information + +#### get_rpc_port() + +```python +get_rpc_port() +``` + +Gets the RPC port that the transfer engine is listening on. + +**Returns:** +- `int`: The RPC port number + +### Buffer Management + +#### allocate_managed_buffer() + +```python +allocate_managed_buffer(length) +``` + +Allocates a managed buffer of the specified size using a buddy allocation system for efficient memory management. + +**Parameters:** +- `length` (int): The size of the buffer to allocate in bytes + +**Returns:** +- `int`: The memory address of the allocated buffer as an integer, or 0 on failure + +#### free_managed_buffer() + +```python +free_managed_buffer(buffer_addr, length) +``` + +Frees a previously allocated managed buffer. + +**Parameters:** +- `buffer_addr` (int): The memory address of the buffer to free +- `length` (int): The size of the buffer in bytes + +**Returns:** +- `int`: 0 on success, negative value on failure + +#### get_first_buffer_address() + +```python +get_first_buffer_address(segment_name) +``` + +Gets the address of the first buffer in a specified segment. + +**Parameters:** +- `segment_name` (str): The name of the segment + +**Returns:** +- `int`: The memory address of the first buffer in the segment + +### Data Transfer Operations + +#### transfer_sync_write() + +```python +transfer_sync_write(target_hostname, buffer, peer_buffer_address, length) +``` + +Performs a synchronous write operation to transfer data from local buffer to remote buffer. + +**Parameters:** +- `target_hostname` (str): The hostname of the target server +- `buffer` (int): The local buffer address +- `peer_buffer_address` (int): The remote buffer address +- `length` (int): The number of bytes to transfer + +**Returns:** +- `int`: 0 on success, negative value on failure + +#### transfer_sync_read() + +```python +transfer_sync_read(target_hostname, buffer, peer_buffer_address, length) +``` + +Performs a synchronous read operation to transfer data from remote buffer to local buffer. + +**Parameters:** +- `target_hostname` (str): The hostname of the target server +- `buffer` (int): The local buffer address +- `peer_buffer_address` (int): The remote buffer address +- `length` (int): The number of bytes to transfer + +**Returns:** +- `int`: 0 on success, negative value on failure + +#### transfer_sync() + +```python +transfer_sync(target_hostname, buffer, peer_buffer_address, length, opcode) +``` + +Performs a synchronous transfer operation with specified opcode. + +**Parameters:** +- `target_hostname` (str): The hostname of the target server +- `buffer` (int): The local buffer address +- `peer_buffer_address` (int): The remote buffer address +- `length` (int): The number of bytes to transfer +- `opcode` (TransferOpcode): The transfer operation type (READ or WRITE) + +**Returns:** +- `int`: 0 on success, negative value on failure + +#### transfer_submit_write() + +```python +transfer_submit_write(target_hostname, buffer, peer_buffer_address, length) +``` + +Submits an asynchronous write operation and returns immediately. + +**Parameters:** +- `target_hostname` (str): The hostname of the target server +- `buffer` (int): The local buffer address +- `peer_buffer_address` (int): The remote buffer address +- `length` (int): The number of bytes to transfer + +**Returns:** +- `int`: Batch ID for tracking the operation, or negative value on failure + +#### transfer_check_status() + +```python +transfer_check_status(batch_id) +``` + +Checks the status of an asynchronous transfer operation. + +**Parameters:** +- `batch_id` (int): The batch ID returned from transfer_submit_write() + +**Returns:** +- `int`: + - 1: Transfer completed successfully + - 0: Transfer still in progress + - -1: Transfer failed + - -2: Transfer timed out + +### Buffer I/O Operations + +#### write_bytes_to_buffer() + +```python +write_bytes_to_buffer(dest_address, src_ptr, length) +``` + +Writes bytes from a Python bytes object to a buffer at the specified address. + +**Parameters:** +- `dest_address` (int): The destination buffer address +- `src_ptr` (bytes): The source bytes to write +- `length` (int): The number of bytes to write + +**Returns:** +- `int`: 0 on success, negative value on failure + +#### read_bytes_from_buffer() + +```python +read_bytes_from_buffer(source_address, length) +``` + +Reads bytes from a buffer at the specified address and returns them as a Python bytes object. + +**Parameters:** +- `source_address` (int): The source buffer address +- `length` (int): The number of bytes to read + +**Returns:** +- `bytes`: The bytes read from the buffer + +### Memory Registration (Experimental) + +#### register_memory() + +```python +register_memory(buffer_addr, capacity) +``` + +Registers a memory region for RDMA access (experimental feature). + +**Parameters:** +- `buffer_addr` (int): The memory address to register +- `capacity` (int): The size of the memory region in bytes + +**Returns:** +- `int`: 0 on success, negative value on failure + +#### unregister_memory() + +```python +unregister_memory(buffer_addr) +``` + +Unregisters a previously registered memory region. + +**Parameters:** +- `buffer_addr` (int): The memory address to unregister + +**Returns:** +- `int`: 0 on success, negative value on failure + +### Enums + +#### TransferOpcode + +```python +TransferOpcode.READ # Read operation +TransferOpcode.WRITE # Write operation +``` + +## Environment Variables + +The Transfer Engine respects the following environment variables: + +- `MC_TRANSFER_TIMEOUT`: Sets the transfer timeout in seconds (default: 30) +- `MC_METADATA_SERVER`: Default metadata server address +- `MC_LEGACY_RPC_PORT_BINDING`: Enables legacy RPC port binding behavior +- `MC_TCP_BIND_ADDRESS`: Specifies the TCP bind address +- `MC_CUSTOM_TOPO_JSON`: Path to custom topology JSON file +- `MC_TE_METRIC`: Enables metrics reporting (set to "1", "true", "yes", or "on") +- `MC_TE_METRIC_INTERVAL_SECONDS`: Sets metrics reporting interval in seconds + +## Usage Examples + +### Basic Setup and Data Transfer + +```python +from mooncake.engine import TransferEngine +import os + +# Create transfer engine instance +engine = TransferEngine() + +# Initialize with basic configuration +engine.initialize( + "127.0.0.1:12345", # local hostname + "127.0.0.1:2379", # metadata server + "rdma", # transport protocol + "" # device name +) + +# Allocate and initialize client buffer (1MB) +client_buffer = np.ones(1024 * 1024, dtype=np.uint8) # Fill with ones +buffer_data = client_buffer.ctypes.data +buffer_data_len = client_buffer.nbytes + +# Prepare data +data = b"Hello, Transfer Engine!" +data_len = len(data) + +engine.register_memory(buffer_data, buffer_data_len) + +# Get Remote Addr from ZMQ or upper-layer inference framework +remote_addr = ?? + +# Transfer data to remote node +ret = engine.transfer_sync_write( + "127.0.0.1:12346", # target hostname + data, # buffer + remote_addr, # peer buffer address + data_len # length +) + +if ret == 0: + print("Data transfer completed successfully") +else: + print(f"Data transfer failed with code {ret}") + +engine.unregister_memory(data) +``` + +### Asynchronous Transfer + +```python +# Submit asynchronous write +batch_id = engine.transfer_submit_write( + "127.0.0.1:12346", # target hostname + local_addr, # buffer + remote_addr, # peer buffer address + data_len # length +) + +if batch_id < 0: + print(f"Failed to submit transfer with code {batch_id}") +else: + # Poll for completion + while True: + status = engine.transfer_check_status(batch_id) + if status == 1: + print("Transfer completed successfully") + break + elif status == -1: + print("Transfer failed") + break + elif status == -2: + print("Transfer timed out") + break + # Transfer still in progress, continue polling + import time + time.sleep(0.001) # Small delay to avoid busy waiting +``` + +### Managed Buffer Allocation + +```python +# Allocate managed buffer +buffer_size = 1024 * 1024 # 1MB +buffer_addr = engine.allocate_managed_buffer(buffer_size) + +if buffer_addr == 0: + print("Failed to allocate buffer") +else: + # Use the buffer + test_data = b"Test data for managed buffer" + engine.write_bytes_to_buffer(buffer_addr, test_data, len(test_data)) + + # Read back + read_data = engine.read_bytes_from_buffer(buffer_addr, len(test_data)) + print(f"Read data: {read_data}") + + # Free the buffer when done + engine.free_managed_buffer(buffer_addr, buffer_size) +``` + +## Error Handling + +All methods return integer status codes: +- `0`: Success +- Negative values: Error codes indicating various failure conditions + +Common error scenarios: +- Network connectivity issues +- Invalid buffer addresses +- Memory allocation failures +- Transfer timeouts +- Metadata server connection problems + +## Performance Considerations + +1. **Buffer Reuse**: Reuse allocated buffers when possible to avoid frequent allocation/deallocation overhead +2. **Batch Operations**: Use `transfer_submit_write()` and `transfer_check_status()` for better throughput when multiple transfers are needed +3. **Memory Alignment**: Ensure buffers are properly aligned for optimal RDMA performance +4. **Timeout Configuration**: Adjust `MC_TRANSFER_TIMEOUT` based on your network characteristics and data sizes + +## Thread Safety + +The Transfer Engine Python API is thread-safe for most operations. However, it's recommended to: +- Use separate TransferEngine instances for different threads when possible +- Avoid concurrent modifications to the same buffer addresses +- Use proper synchronization when sharing buffer addresses between threads + +## Troubleshooting + +1. **Initialization Failures**: Check metadata server connectivity and network configuration +2. **Transfer Failures**: Verify target hostname is correct and network connectivity is established +3. **Memory Issues**: Ensure sufficient system memory and proper buffer alignment +4. **Performance Issues**: Check RDMA device configuration and network topology \ No newline at end of file