-
Notifications
You must be signed in to change notification settings - Fork 8k
[doc][llm] Add docs for serving LLMs with TPUs #65026
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
6d73851
[doc][llm] Add TPU LLM deployment docs
jeffreywang88 d6ec88e
Apply suggestions from code review
jeffreywang88 342f94a
Apply suggestion from @gemini-code-assist[bot]
jeffreywang88 dd2dab9
CR feedback
jeffreywang88 7bff1f5
Add TPU visualizer link
jeffreywang88 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # flake8: noqa | ||
| """ | ||
| Example Ray Serve LLM application for a multi-host TPU slice. | ||
| """ | ||
|
|
||
| # __serve_tpu_multihost_start__ | ||
| from ray import serve | ||
| from ray.serve.llm import LLMConfig, LLMServingArgs, build_openai_app | ||
|
|
||
| llm_config = LLMConfig( | ||
| model_loading_config=dict( | ||
| model_id="google/gemma-4-31B-it", | ||
| model_source="/data/google/gemma-4-31B-it", | ||
| ), | ||
| accelerator_type="TPU-V6E", | ||
| accelerator_config={"kind": "tpu", "topology": "4x4"}, | ||
| engine_kwargs=dict( | ||
| tensor_parallel_size=16, | ||
| max_model_len=8192, | ||
| max_num_batched_tokens=8192, | ||
| distributed_executor_backend="ray", | ||
| ), | ||
| ) | ||
|
|
||
| app = build_openai_app(LLMServingArgs(llm_configs=[llm_config])) | ||
|
|
||
| if __name__ == "__main__": | ||
| serve.run(app, blocking=True) | ||
| # __serve_tpu_multihost_end__ | ||
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| --- | ||
| myst: | ||
| html_meta: | ||
| description: "Serve LLMs on single-host and multi-host TPU slices with Ray Serve LLM, including topology-aware placement groups and a multi-host vLLM TPU example." | ||
| --- | ||
|
|
||
| (serve-llm-tpu)= | ||
| # TPU serving | ||
|
jeffreywang88 marked this conversation as resolved.
|
||
|
|
||
| Ray Serve LLM can run a vLLM TPU engine on single-host and multi-host TPU slices, where a TPU slice is a group of interconnected TPU chips. Use this when your Ray cluster already exposes TPU resources and TPU node labels, and your container image includes the TPU variant of vLLM from `tpu-inference`. For Kubernetes setup, see {doc}`Use TPUs with KubeRay </cluster/kubernetes/user-guides/tpu>`. | ||
|
|
||
| ## Topology and placement | ||
|
|
||
| A TPU topology describes the chip grid in one physical TPU slice. For example, a v6e `4x4` slice has 16 chips. Multi-host slices spread those chips across multiple TPU hosts connected by the TPU interconnect. For v6e `4x4`, that usually means four hosts with four chips each. For visualization, check out [TPU Topology Visualizer](https://tpu-visualizer.uc.r.appspot.com/). | ||
|
|
||
| Ray Serve LLM uses `tensor_parallel_size * pipeline_parallel_size` as the number of TPU chips that one model replica requests. When you also set a TPU topology, Ray Serve LLM computes the number of chips per host and creates one placement group bundle per TPU host: | ||
|
|
||
| ```python | ||
| LLMConfig( | ||
| accelerator_type="TPU-V6E", | ||
| accelerator_config={"kind": "tpu", "topology": "4x4"}, | ||
| engine_kwargs={"tensor_parallel_size": 16}, | ||
| ) | ||
| ``` | ||
|
|
||
| For a v6e `4x4` slice, this produces four host-level bundles: | ||
|
|
||
| ```python | ||
| [ | ||
| {"TPU": 4, "accelerator_type:TPU-V6E": 0.001}, | ||
| {"TPU": 4, "accelerator_type:TPU-V6E": 0.001}, | ||
| {"TPU": 4, "accelerator_type:TPU-V6E": 0.001}, | ||
| {"TPU": 4, "accelerator_type:TPU-V6E": 0.001}, | ||
| ] | ||
| ``` | ||
|
|
||
| The model still spans all 16 chips because `tensor_parallel_size=16`. The bundle shape only tells Ray how to reserve the hosts that own those chips. If you need per-chip bundles, set `placement_group_config={"bundle_per_worker": {"TPU": 1}}`. | ||
|
jeffreywang88 marked this conversation as resolved.
|
||
|
|
||
| ```{figure} ../images/ray_serve_llm_tpu.png | ||
| --- | ||
| width: 100% | ||
| name: ray-serve-llm-tpu-placement | ||
| alt: One Ray Serve LLM replica spanning a v6e 4x4 TPU slice, with one placement group bundle per TPU host and four TPU chips reserved in each bundle. | ||
| --- | ||
| Topology-aware TPU placement for one Ray Serve LLM replica. | ||
| ``` | ||
|
jeffreywang88 marked this conversation as resolved.
|
||
|
|
||
| :::{note} | ||
| TPU support in Ray Serve LLM is topology-aware when you set `accelerator_config={"kind": "tpu", "topology": ...}`. Without a topology, Ray Serve LLM falls back to a regular placement group with per-chip `{"TPU": 1}` bundles. | ||
| ::: | ||
|
|
||
| ## `SlicePlacementGroup` | ||
|
|
||
| For topology-aware TPU configs, Ray Serve LLM creates a {class}`~ray.util.tpu.SlicePlacementGroup` instead of a plain placement group. `SlicePlacementGroup` reserves a matching TPU slice, reads its `ray.io/tpu-slice-name` label, and creates the worker placement group with a per-bundle label selector that pins all bundles to that same physical slice. | ||
|
|
||
| This makes the TPU slice an atomic scheduling unit. A replica reserves the complete slice it needs, and the placement group doesn't span unrelated slices. | ||
|
|
||
| ## How the TPU vLLM executor uses the bundles | ||
|
|
||
| The `tpu-inference` [Ray executor](https://github.com/vllm-project/tpu-inference/blob/main/tpu_inference/executors/ray_distributed_executor_v2.py) checks `parallel_config.placement_group`. When Ray Serve LLM already provided one, the executor reuses it instead of creating its own. | ||
|
|
||
| The executor then does the following: | ||
|
|
||
| 1. Selects the TPU bundles from the placement group. | ||
| 1. Reads the TPU count from each bundle. | ||
| 1. Starts one Ray worker actor per bundle with `PlacementGroupSchedulingStrategy`, pinning each actor to its bundle. | ||
|
jeffreywang88 marked this conversation as resolved.
|
||
|
|
||
| With the default topology-aware bundles, one vLLM worker actor maps to one TPU host and consumes all local TPU chips on that host. The worker process uses the chips across the multi-host slice. Otherwise, manually setting `{"TPU": 1}` results in the creation of one worker per chip. | ||
|
|
||
| ## Example | ||
|
|
||
| Build the image from the vLLM TPU base image and install a Ray wheel that includes TPU topology support. | ||
|
|
||
| ::::{tab-set} | ||
|
|
||
| :::{tab-item} Dockerfile | ||
|
|
||
| ```dockerfile | ||
| FROM vllm/vllm-tpu:v0.21.0 | ||
|
|
||
| ENV VLLM_TARGET_DEVICE=tpu | ||
| ENV VLLM_XLA_CACHE_PATH=/tmp/vllm_xla_cache | ||
| ENV JAX_PLATFORMS=tpu,cpu | ||
| ENV TPU_MULTIHOST_BACKEND=ray | ||
| ENV TPU_BACKEND_TYPE=jax | ||
| ENV ENABLE_PJRT_COMPATIBILITY=true | ||
|
|
||
| USER root | ||
|
|
||
| # Use a released Ray version or wheel URL that contains TPU topology support. | ||
| ARG RAY_PACKAGE="ray" | ||
| RUN pip install --no-cache-dir -U "${RAY_PACKAGE}" && \ | ||
| pip install --no-cache-dir --no-deps "ray[llm]" | ||
|
|
||
| COPY serve_tpu_multihost.py /home/ray/serve_tpu_multihost.py | ||
| ``` | ||
| ::: | ||
|
jeffreywang88 marked this conversation as resolved.
|
||
|
|
||
| :::{tab-item} Python | ||
|
|
||
| ```{literalinclude} ../../../llm/doc_code/serve/tpu/serve_tpu_multihost.py | ||
| :language: python | ||
| :start-after: __serve_tpu_multihost_start__ | ||
| :end-before: __serve_tpu_multihost_end__ | ||
| ``` | ||
| ::: | ||
|
|
||
| :::: | ||
|
|
||
| This example serves `google/gemma-4-31B-it` on one v6e `4x4` slice with `tensor_parallel_size=16`. Set `model_source` to a local or mounted model path, or another path that all TPU hosts can read. | ||
|
|
||
| ## See also | ||
|
|
||
| - {doc}`Use TPUs with KubeRay </cluster/kubernetes/user-guides/tpu>` | ||
| - [Serve Gemma open models using multi-host TPUs on GKE with Ray](https://docs.cloud.google.com/kubernetes-engine/docs/tutorials/serve-multi-host-tpu-llm) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.