|
| 1 | +# Multi Node Test |
| 2 | + |
| 3 | +Multi-Node CI is designed to test distributed scenarios of very large models, eg: disaggregated_prefill multi DP across multi nodes and so on. |
| 4 | + |
| 5 | +## How is works |
| 6 | + |
| 7 | +The following picture shows the basic deployment view of the multi-node CI mechanism, It shows how the github action interact with [lws](https://lws.sigs.k8s.io/docs/overview/) (a kind of kubernetes crd resource) |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | +From the workflow perspective, we can see how the final test script is executed, The key point is that these two [lws.yaml and run.sh](https://github.com/vllm-project/vllm-ascend/tree/main/tests/e2e/nightly/multi_node/scripts), The former defines how our k8s cluster is pulled up, and the latter defines the entry script when the pod is started, Each node executes different logic according to the [LWS_WORKER_INDEX](https://lws.sigs.k8s.io/docs/reference/labels-annotations-and-environment-variables/) environment variable, so that multiple nodes can form a distributed cluster to perform tasks. |
| 12 | + |
| 13 | + |
| 14 | + |
| 15 | +## How to contribute |
| 16 | + |
| 17 | +1. Upload custom weights |
| 18 | + |
| 19 | + If you need customized weights, for example, you quantized a w8a8 weight for DeepSeek-V3 and you want your weight to run on CI, Uploading weights to ModelScope's [vllm-ascend](https://www.modelscope.cn/organization/vllm-ascend) organization is welcome, If you do not have permission to upload, please contact @Potabk |
| 20 | + |
| 21 | +2. Add config yaml |
| 22 | + |
| 23 | + As the entrypoint script [run.sh](https://github.com/vllm-project/vllm-ascend/blob/0bf3f21a987aede366ec4629ad0ffec8e32fe90d/tests/e2e/nightly/multi_node/scripts/run.sh#L106) shows, A k8s pod startup means traversing all *.yaml files in the [directory](https://github.com/vllm-project/vllm-ascend/tree/main/tests/e2e/nightly/multi_node/config/models), reading and executing according to different configurations, so what we need to do is just add "yamls" like [DeepSeek-V3.yaml](https://github.com/vllm-project/vllm-ascend/blob/main/tests/e2e/nightly/multi_node/config/models/DeepSeek-V3.yaml). |
| 24 | + |
| 25 | + Suppose you have **2 nodes** running a 1P1D setup (1 Prefillers + 1 Decoder): |
| 26 | + |
| 27 | + you may add a config file looks like: |
| 28 | + |
| 29 | + ```yaml |
| 30 | + test_name: "test DeepSeek-V3 disaggregated_prefill" |
| 31 | + # the model being tested |
| 32 | + model: "vllm-ascend/DeepSeek-V3-W8A8" |
| 33 | + # how large the cluster is |
| 34 | + num_nodes: 2 |
| 35 | + npu_per_node: 16 |
| 36 | + # All env vars you need should add it here |
| 37 | + env_common: |
| 38 | + VLLM_USE_MODELSCOPE: true |
| 39 | + OMP_PROC_BIND: false |
| 40 | + OMP_NUM_THREADS: 100 |
| 41 | + HCCL_BUFFSIZE: 1024 |
| 42 | + SERVER_PORT: 8080 |
| 43 | + disaggregated_prefill: |
| 44 | + enabled: true |
| 45 | + # node index(a list) which meet all the conditions: |
| 46 | + # - prefiller |
| 47 | + # - no headless(have api server) |
| 48 | + prefiller_host_index: [0] |
| 49 | + # node index(a list) which meet all the conditions: |
| 50 | + # - decoder |
| 51 | + # - no headless(have api server) |
| 52 | + decoder_host_index: [1] |
| 53 | + |
| 54 | + # Add each node's vllm serve cli command just like you runs locally |
| 55 | + deployment: |
| 56 | + - |
| 57 | + server_cmd: > |
| 58 | + vllm serve ... |
| 59 | + - |
| 60 | + server_cmd: > |
| 61 | + vllm serve ... |
| 62 | + benchmarks: |
| 63 | + perf: |
| 64 | + # fill with performance test kwargs |
| 65 | + acc: |
| 66 | + # fill with accuracy test kwargs |
| 67 | + ``` |
| 68 | + |
| 69 | +3. Add the case to nightly workflow |
| 70 | +currently, the multi-node test workflow defined in the [vllm_ascend_test_nightly_a2/a3.yaml](https://github.com/vllm-project/vllm-ascend/blob/main/.github/workflows/vllm_ascend_test_nightly_a3.yaml) |
| 71 | + |
| 72 | + ```yaml |
| 73 | + multi-node-tests: |
| 74 | + needs: single-node-tests |
| 75 | + if: always() && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') |
| 76 | + strategy: |
| 77 | + fail-fast: false |
| 78 | + max-parallel: 1 |
| 79 | + matrix: |
| 80 | + test_config: |
| 81 | + - name: multi-node-deepseek-pd |
| 82 | + config_file_path: tests/e2e/nightly/multi_node/config/models/DeepSeek-V3.yaml |
| 83 | + size: 2 |
| 84 | + - name: multi-node-qwen3-dp |
| 85 | + config_file_path: tests/e2e/nightly/multi_node/config/models/Qwen3-235B-A3B.yaml |
| 86 | + size: 2 |
| 87 | + - name: multi-node-dpsk-4node-pd |
| 88 | + config_file_path: tests/e2e/nightly/multi_node/config/models/DeepSeek-R1-W8A8.yaml |
| 89 | + size: 4 |
| 90 | + uses: ./.github/workflows/_e2e_nightly_multi_node.yaml |
| 91 | + with: |
| 92 | + soc_version: a3 |
| 93 | + image: m.daocloud.io/quay.io/ascend/cann:8.3.rc1-a3-ubuntu22.04-py3.11 |
| 94 | + replicas: 1 |
| 95 | + size: ${{ matrix.test_config.size }} |
| 96 | + config_file_path: ${{ matrix.test_config.config_file_path }} |
| 97 | + ``` |
| 98 | + |
| 99 | +The matrix above defines all the parameters required to add a multi-machine use case, The parameters worth paying attention to (I mean if you are adding a new use case) are size and the path to the yaml configuration file. The former defines the number of nodes required for your use case, and the latter defines the path to the configuration file you have completed in step 2. |
0 commit comments