Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
4a60b94
Rebased
pgusto34 Nov 26, 2025
ebee722
WIP
pgusto34 Nov 26, 2025
88a2eaf
Updated requirements.txt
pgusto34 Nov 26, 2025
c766869
stencil backwards_compile task on StageActor captures a partial backw…
meganfrisella Nov 25, 2025
3040164
Rebased
pgusto34 Nov 26, 2025
0b16c7b
WIP
pgusto34 Nov 26, 2025
8157cd7
Updated requirements.txt
pgusto34 Nov 26, 2025
c272be4
Split backwards example script
pgusto34 Nov 26, 2025
ea2139e
Removed requirements.txt file and updated README in place of it
pgusto34 Nov 26, 2025
65952d5
Graph PNGs
pgusto34 Nov 26, 2025
c3f6979
Commented out NCCL
pgusto34 Dec 1, 2025
9330880
Merged changes
pgusto34 Dec 1, 2025
756febe
Merge remote-tracking branch 'refs/remotes/origin/ZeroBubble' into Ze…
pgusto34 Dec 1, 2025
f5d1b63
Initial ZeroBubble implementation
pgusto34 Dec 9, 2025
832385c
Added graph pruning to optimize split backward pass for ZB, including…
pgusto34 Jan 14, 2026
995e7a7
Merge remote-tracking branch 'origin/main' into ZeroBubble
Jan 20, 2026
955d7b2
Dockerfile and run.sh to deploy Piper in a container
pgusto34 Jan 21, 2026
931bb45
Code cleanup and updated validate schedule to account for split backw…
pgusto34 Jan 28, 2026
ee7bab2
Merge branch 'main' into ZeroBubble
pgusto34 Jan 28, 2026
e4e8b5b
add centralized comm op scheduling and implement comm ops for DP grad…
meganfrisella Feb 2, 2026
11691b2
a2a support for EP in Piper. Implemented with a graph transformation …
meganfrisella Feb 10, 2026
d6afed6
piper manages p2p comm. committing code as it stands with potential b…
meganfrisella Feb 12, 2026
6b27bd3
fix device-side assertion when running multiple iters
sbhTWR Feb 12, 2026
c506131
remove input clear on actor
meganfrisella Feb 12, 2026
cc6dda2
Revert "fix device-side assertion when running multiple iters"
meganfrisella Feb 13, 2026
b6b8f48
Reapply "fix device-side assertion when running multiple iters"
meganfrisella Feb 13, 2026
c9cbd32
Revert "remove input clear on actor"
meganfrisella Feb 13, 2026
4e6054f
clean up test files and timing code
meganfrisella Feb 13, 2026
900348f
rm files
meganfrisella Feb 13, 2026
d528f48
remove actor._forward requires_grad hack
meganfrisella Feb 13, 2026
51b47b1
deadlock happens when --mbs > 1 due to p2p send/recv not ordered prop…
meganfrisella Feb 13, 2026
789a2f5
manually reorder p2p ops for marked schedule tasks
meganfrisella Feb 18, 2026
f25e515
merge
meganfrisella Feb 18, 2026
e4b3372
Revert "merge"
meganfrisella Feb 18, 2026
4db0979
Order P2P ops
AndyUB Feb 18, 2026
92ace46
use comp stream for fwd/bwd computation
meganfrisella Feb 18, 2026
1fd1aef
fix: reset to start of p2p schedule before each iteration
AndyUB Feb 19, 2026
02bf621
scripts and results
AndyUB Feb 19, 2026
4054872
Pushing latest profiling code before merging
pgusto34 Feb 19, 2026
06e1787
remove _comm_loop and launch dp comm ops on single actor thread
meganfrisella Feb 19, 2026
995b676
Merge remote-tracking branch 'origin/main' into ZeroBubble
pgusto34 Feb 20, 2026
e6e32dd
Refactoring from /src to /piper
pgusto34 Feb 20, 2026
21ec388
dag schedules instead of 2D array with graph visualization
meganfrisella Feb 20, 2026
ce765e9
verify p2p correctness: execution matches schedule
AndyUB Feb 20, 2026
42fc7c7
Debugging Torch autograd error
pgusto34 Feb 20, 2026
274c0aa
add_param_group patch to fix split backward autograd issue
pgusto34 Feb 20, 2026
dfab522
fix: explicit send and recv tensors for fwd P2Ps
AndyUB Feb 20, 2026
13bd51d
Reverted the stage_id != 0 check in forward to match main
pgusto34 Feb 20, 2026
78a61d5
p2p ordering test v0
AndyUB Feb 22, 2026
033f241
fix: sync streams for p2p ops
AndyUB Feb 23, 2026
b1518d7
fix: cache sent and received tensors; sync streams for p2p ops
AndyUB Feb 23, 2026
d3018b1
Add DualPipeV schedule, FWD_BWD tasks run sequentially
meganfrisella Feb 23, 2026
0873358
coordinator gets its own GPU, will change in future with meta compila…
meganfrisella Feb 23, 2026
111ea8c
merge Andy's p2p memory bug fix. Reuse p2p_cache to save tensors betw…
meganfrisella Feb 23, 2026
98adc2f
fix: rebase and update outdated p2p ops and mixtral test file.
Conless Feb 24, 2026
fc1cbb4
overlap p2p, batch p2p ops for outputs with multiple tensors. add ove…
meganfrisella Feb 24, 2026
05ea925
test_tracing.py and Llama 70B config
pgusto34 Feb 25, 2026
1709416
Llama changes to allow for meta device tracing
pgusto34 Feb 25, 2026
c41d7ca
isend/irecv -> send/recv. in order_p2p_comm schedule FWD p2p ops befo…
meganfrisella Feb 25, 2026
f435e1e
feat: basic DualPipe-style overlapping.
Conless Feb 24, 2026
3c00543
schedule _forward_backward p2p comms on the coordinator (in piper_exe…
meganfrisella Feb 25, 2026
6a32227
rever file names to piper_*
meganfrisella Feb 25, 2026
60ce835
Merge ZB
meganfrisella Feb 26, 2026
15a7525
DualPipeV schedule with ZB
meganfrisella Feb 26, 2026
0e22cca
fix: stream wait logic.
Conless Feb 26, 2026
18b2876
merge zb into dualpipe overlapping
meganfrisella Feb 27, 2026
08f1b63
[Buggy] Initial deferred init implementation
pgusto34 Feb 27, 2026
165d8df
fix: put paired fwd/bwd on specific streams and fix stream wait.
Conless Feb 27, 2026
6c29146
feat: comm/comp overlap working with thread-based approach.
Conless Feb 27, 2026
778beda
Deferred Init Working
pgusto34 Feb 28, 2026
542413d
Code cleanup for PR
pgusto34 Feb 28, 2026
6faf0cd
backward hook fix for split backwards pass
meganfrisella Mar 2, 2026
80346c0
merge deferred init
meganfrisella Mar 2, 2026
4a52dfe
integrate qwen with torch.ops workaround
sbhTWR Mar 3, 2026
cfdadd3
Merge remote-tracking branch 'origin/dualpipe_overlap' into moe_eval
sbhTWR Mar 3, 2026
70fe692
use cuda events to wait for recv in compute tasks rather than p2p tas…
meganfrisella Mar 5, 2026
d3914f5
1. order p2p operations by compute task dispatch order to avoid deadl…
meganfrisella Mar 6, 2026
483bb9b
Enable profiling models that don't fit into memory for auto stage spl…
meganfrisella Mar 6, 2026
a8078dc
(WIP) experimental: ZeRO1 with per-param sharding
AndyUB Mar 9, 2026
8e002eb
(WIP) ZeRO1 initial profiling
AndyUB Mar 9, 2026
b709aff
AC implementation plus ray placement groups
meganfrisella Mar 9, 2026
aafe9c3
(WIP) ZeRO1 DP2 PP2 profiling
AndyUB Mar 9, 2026
bc80f90
integrate qwen model from torchtitan with workarounds
sbhTWR Mar 10, 2026
752de6b
moe changes
sbhTWR Mar 10, 2026
69073a3
Merge remote-tracking branch 'origin/dualpipe_overlap' into moe_eval
sbhTWR Mar 10, 2026
3de94cc
moe changes
sbhTWR Mar 10, 2026
77b4d77
enable bf16 support
meganfrisella Mar 11, 2026
da9c620
enable bf16
sbhTWR Mar 11, 2026
3a39f53
(WIP) split ZeRO1 and ZeRO2
AndyUB Mar 11, 2026
2c85e9c
run ZeRO1 and ZeRO2 on LLAMA_DEBUG
AndyUB Mar 11, 2026
b79bf84
NCCL monitor identifies overlapping NCCL kernels. also fix DP allredu…
meganfrisella Mar 12, 2026
856d3fc
zero-3 implementation. shape mismatch bug in backward pass
meganfrisella Mar 12, 2026
8119059
new Piper backend based on DAG IR approach. The controller builds a u…
meganfrisella Mar 24, 2026
f06d50f
remove old actor compute method impls.
meganfrisella Mar 24, 2026
00231c4
merge shubham's qwen model into dag-ir
meganfrisella Mar 25, 2026
ff37fa6
update llama test file with new DAG API. known bug: unexpected stage …
meganfrisella Mar 25, 2026
4460cb4
slow startup time fix: use 2 pp communicators per pp group rather tha…
meganfrisella Mar 31, 2026
7c7a9fd
Change pipeline schedule interface (no None entries required, use log…
meganfrisella Apr 9, 2026
70e7bdc
add per-bucket AC (split buckets into N ac segments). revert flat par…
meganfrisella Apr 13, 2026
9be79a8
merge zero into dag-ir and update to manage params/weights per-bucket…
meganfrisella Apr 14, 2026
99f48f1
background dag visualization. known bug: illegal memory access in zero 3
meganfrisella Apr 14, 2026
2c6c637
zero overlapping performance debugging
meganfrisella Apr 15, 2026
12aaabe
flash attention backend for qwen. update sweep scripts
meganfrisella Apr 16, 2026
ddc8a35
implement chunk overlapping
meganfrisella Apr 19, 2026
a5e1387
update zero e2e script
meganfrisella Apr 19, 2026
8655cb6
typo
meganfrisella Apr 19, 2026
3674a50
adjust run_dag priorities
meganfrisella Apr 19, 2026
655a42d
zero2 startup memory fix
sbhTWR Apr 22, 2026
05c196c
enable pp to be the outer dimension
Conless Apr 23, 2026
18a7f07
add nsight backtrace to runtime env
meganfrisella Apr 23, 2026
18a48ce
meerge remote-tracking branch 'origin/dev-yi' into dag-ir
meganfrisella Apr 23, 2026
303c7ed
debug schedule directives
meganfrisella Jun 1, 2026
8d851b3
refactor
meganfrisella Jun 1, 2026
bbd4ae8
artifact dir with commands to run eval
meganfrisella Jun 3, 2026
0c252c7
initial release
meganfrisella Jun 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Tests

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

- name: Run CPU tests
run: python -m pytest -m "not gpu" -v test
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ __pycache__/

.venv
piper.egg-info/
out/
out/
.vscode/
.codex
ec2-trust-policy.json
25 changes: 25 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM rayproject/ray:2.44.1-py310-cu128

USER root

RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates wget && \
. /etc/os-release && \
arch="$(dpkg --print-architecture)" && \
case "$arch" in \
amd64) cuda_arch="x86_64" ;; \
arm64) cuda_arch="sbsa" ;; \
*) echo "Unsupported architecture: $arch" >&2; exit 1 ;; \
esac && \
cuda_repo="https://developer.download.nvidia.com/compute/cuda/repos/${ID}${VERSION_ID//./}/${cuda_arch}" && \
wget -q "${cuda_repo}/cuda-keyring_1.1-1_all.deb" -O /tmp/cuda-keyring.deb && \
dpkg -i /tmp/cuda-keyring.deb && \
apt-get update && \
apt-get install -y --no-install-recommends cuda-nsight-systems-12-8 && \
rm -rf /var/lib/apt/lists/* /tmp/cuda-keyring.deb

USER ray

COPY requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt \
--extra-index-url https://download.pytorch.org/whl/cu128
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Megan Frisella

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
250 changes: 200 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,203 @@
# Piper

Piper is a PyTorch library for training large models with flexible pipeline parallel schedules.

## Environment setup: conda
We assume a Linux-based environment

1. Create a conda environment with `python==3.10`
2. Install the requirements in `requirements.txt`
3. Modify PyTorch and Ray dependencies according to the instructions below

## Modifying Ray dependency

**Ray**

Tensor transport backends currently only support 1 return value per task.
- WIP: Upstream this into Ray.
- Modifications (2): Comment out the [assertion in ActorMethod._remote()](https://github.com/ray-project/ray/blob/b70d990db786a1f2259dec0504acccf2590353f3/python/ray/actor.py#L824-L828) and add logic for [handling multiple return values with a GPU object manager](https://github.com/ray-project/ray/blob/b70d990db786a1f2259dec0504acccf2590353f3/python/ray/actor.py#L880-L887).
```
####### PIPER MODIFICATION START #######
# if num_returns != 1:
# raise ValueError(
# f"Currently, methods with tensor_transport={tensor_transport.name} only support 1 return value. "
# "Please make sure the actor method is decorated with `@ray.method(num_returns=1)` (the default)."
# )
####### PIPER MODIFICATION END #######
```
```
####### PIPER MODIFICATION START #######
gpu_object_manager = ray._private.worker.global_worker.gpu_object_manager
if isinstance(object_refs, ObjectRef):
object_ref = object_refs
gpu_object_manager.add_gpu_object_ref(
object_ref, self._actor, tensor_transport
)
else:
for object_ref in object_refs:
assert isinstance(object_ref, ObjectRef)
gpu_object_manager.add_gpu_object_ref(
object_ref, self._actor, tensor_transport
)
####### PIPER MODIFICATION END #######
```

## Training Llama in Piper
The llama test program `test/test_llama.py` supports GPipe, 1F1B and interleaved 1F1B schedules for 2 or 4 devices.
The `test/models/llama.py` file has example `forward` methods for one stage, two stage, and four stage partitions.
Ensure that the correct `forward` method is uncommented for the desired schedule (e.g. two stage for 1F1B on 2 devices, four stage for interleaved 1F1B on two devices).
DP training can also be turned on with the `dp_degree` flag.
Run the Llama test program for the 1F1B schedule for two devices:
```
python3 -m test.test_llama --model LLAMA_DEBUG --schedule 1f1b --num_stages 2 --pp_degree 2 --dp_degree 1
[![arXiv](https://img.shields.io/badge/arXiv-TODO-b31b1b.svg)](TODO)

New distributed training strategies should not require new distributed runtimes; Piper gives PyTorch users direct control over model placement and GPU scheduling with lightweight annotations and a small scheduling language.

## Updates

* 2026-06 - Blog post: [User-Controlled Distributed Training for PyTorch](TODO).
* 2025-10 - Paper released on arXiv: [Piper: Towards Flexible Pipeline Parallelism for PyTorch](TODO).

## Introduction

Large training jobs increasingly combine multiple parallelism strategies such as pipeline, data, and expert parallelism with ZeRO-style sharding, creating placement and GPU scheduling choices that current frameworks cannot express cleanly.
Today, ML researchers and practitioners choose between one-off specialized systems that perform well but are hard to adapt, and general-purpose frameworks that are easier to use but expose limited control.

Piper is a user-controllable distributed training system for PyTorch that separates model placement and GPU scheduling from model code and runtime implementation.
With lightweight model annotations and a small scheduling language, Piper lets users express, visualize, profile, and run high-performance training schedules such as DualPipe-style pipeline- and expert-parallel overlap.

## Architecture

![Piper architecture](figs/architecture.jpg)

Piper has two user-facing inputs:

* An annotated PyTorch model: standard model code with lightweight tags for schedulable regions such as pipeline stages and MoE experts.
* A schedule-directive program: instructions that tell the Piper compiler how to shard, replicate, order, and overlap those schedulable regions.

The compiler traces the model with TorchDynamo, splits the graph by Piper annotations, builds a distributed training DAG IR, and applies DAG rewrites according to the schedule directives.
The directive rewrites insert point-to-point pipeline communication, DP collectives, ZeRO gather/scatter collectives, EP all-to-all communication, temporal edges, device assignments, and logical stream assignments.

The runtime decomposes the global DAG into per-device execution plans and runs them on Ray actors.
Each actor manages local CUDA streams, process groups/communicators, model-state buffers, and intermediate tensors.

## Installation

Requires Python 3.10+ on Linux with CUDA GPUs.
The current setup has been tested with Python 3.10 and CUDA 12.x.

```bash
python3.10 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e .
```

If you do not already have Python 3.10 locally:

```bash
conda create -n piper python=3.10 -y
conda activate piper
python -m pip install --upgrade pip
python -m pip install -e .
```

## Quickstart

From the repository root, run the Qwen example with a DualPipeV schedule:

```bash
python examples/test_harness.py \
--test-file examples/test_qwen.py \
--base-schedule examples/base-schedules/pp4_dp2_ep2_v_placement.json \
--schedule dualpipev \
--ranks 2 \
--mbs 4
```

The base schedule `pp4_dp2_ep2_v_placement.json` describes a PP x DP x EP placement with four annotated pipeline regions mapped onto two physical pipeline ranks in a V layout.
Regions `PP=0` and `PP=3` run on device group `[0, 2]`, while `PP=1` and `PP=2` run on device group `[1, 3]`.
Within each device group, Piper replicates non-expert regions for DP and shards expert regions for EP.
This example expects four visible CUDA devices.
The harness appends DualPipeV `split` and `order` directives for two physical pipeline ranks and four microbatches.

Run the Qwen example with PP x ZeRO-3 1F1B schedule:

```bash
python examples/test_harness.py \
--test-file examples/test_qwen.py \
--base-schedule examples/base-schedules/pp2_dp2_ep2_zero3.json \
--schedule 1f1b \
--ranks 2 \
--mbs 4
```

The base schedule `pp2_dp2_ep2_zero3.json` describes a PP x DP x EP placement with two pipeline stages, DP degree two, EP sharding, and ZeRO-3-style gradient and parameter sharding.
Stage `PP=0` runs on device group `[0, 2]`, while `PP=1` runs on device group `[1, 3]`.
This example also expects four visible CUDA devices.
The harness appends 1F1B `split` and `order` directives for two pipeline ranks and four microbatches.
Each run creates `out/<timestamp>/` with the complete generated schedule and metrics.

## Overview of Inputs

### Annotations

`piper.annotate(tag)` is a context manager that attaches Piper metadata to all PyTorch operations traced inside the scope.
The `tag` is a non-empty string naming a schedulable dimension of the model, such as `PP` for pipeline regions or `EP` for expert regions.
For each tag name, Piper assigns integer indices in trace order, so repeated `piper.annotate("PP")` scopes become `PP=0`, `PP=1`, and so on.

The schedule directives program uses these tag names and indices in filters to select regions of the traced model.
For example, a filter can select one concrete region by its tag index, all regions with a tag, or regions that match a combination of tags.
See the blog walkthrough section on [annotating a Qwen3 MoE model](TODO) for an example and further details.

### Schedule Directives Program

A schedule directive program is a JSON array of directive objects.
Each directive has an `op` string naming the rewrite to apply to the distributed training DAG IR.
Most directives use a `filter` object to select the model region to apply the directive to.
The `order` directive uses `filters` to describe a sequence of filter groups.
A `filter` is a JSON object whose keys are tag names and whose values are the tag indices to match.

Filter keys can refer to annotation tags, new tags added by previous directives, or the compiler-provided `PASS` tag which supports `F` (forward), `B` (backward), `BI` (backward for inputs), and `BW` (backward for weights) for different training step stages.
Filter values can be tag indices or the special value `"*"` to match any concrete index for the key.

The empty filter `{}` matches the entire DAG IR.
All key/value pairs in a filter are conjunctive, so `{"PP": 1, "EP": "*"}` matches nodes that are in pipeline region `PP=1` and have any `EP` index.

Supported directives:

* `place` assigns matched compute regions to device groups and names the stream used for inserted PP send/recv communication.
* `op`: `"place"`
* `filter`: Selects the model regions to place.
* `devices`: Non-empty list of CUDA device IDs for the placement group.
* `stream`: Optional logical stream name for inserted point-to-point communication.
* `replicate` replicates matched regions across devices and inserts DP synchronization.
* `op`: `"replicate"`.
* `filter`: Selects the model regions to replicate.
* `devices`: Non-empty list of CUDA device IDs across which the region is replicated.
* `reduce_stream`: Optional logical stream name for gradient reduction collective communication.
* `gather_stream`: Optional logical stream name for ZeRO-3 parameter materialization collective communication.
* `bucket_size`: Optional parameter bucket size in MB for finer-grained synchronization.
* `shard_grads`: Optional boolean enabling ZeRO-2-style gradient sharding.
* `shard_params`: Optional boolean enabling ZeRO-3-style parameter sharding.
* `shard` shards matched regions across devices and inserts all-to-all communication, typically for expert regions.
* `op`: `"shard"`
* `filter`: Selects the model regions to shard.
* `devices`: Non-empty list of CUDA device IDs across which the region is sharded.
* `stream`: Optional logical stream name for inserted all-to-all collective communication.
* `split` duplicates the matched DAG by a named microbatch dimension.
* `op`: `"split"`
* `filter`: Selects the sub-DAG to duplicate.
* `dim_name`: Non-empty string naming the new split dimension.
* `num_microbatches`: Positive integer number of copies to create.
* `order` adds temporal dependencies between filter groups.
* `op`: `"order"`
* `filters`: List of at least two non-empty filter groups.
* Each filter group is a list of filter objects that occupy the same ordering slot.
* Consecutive filter groups create temporal dependencies from one slot to the next.
* Multiple filters in the same group permit Piper to interleave those sub-DAGs.

In practice, base schedules under `examples/base-schedules/` describe model placement and composed parallelism choices, while `examples/test_harness.py` appends generated `split` and `order` directives for schedule families such as `1f1b`, `interleaved_1f1b`, `zerobubble`, and `dualpipev`.
For more detail, see the blog walkthrough sections on [PP x DP x EP placement](https://github.com/uw-syfi/uw-syfi.github.io/blob/piper-blog/_posts/2026-06-05-piper.md#scheduling-dualpipe-like-pp-x-dp-x-ep-model-placement), [DualPipe-like pipeline scheduling](https://github.com/uw-syfi/uw-syfi.github.io/blob/piper-blog/_posts/2026-06-05-piper.md#scheduling-a-dualpipe-like-pipeline-schedule), and [schedule builders](https://github.com/uw-syfi/uw-syfi.github.io/blob/piper-blog/_posts/2026-06-05-piper.md#generating-directives-with-schedule-builders).

## Overview of Outputs

Every harness run creates a timestamped directory under `out/`:

```text
out/<timestamp>/
|-- <schedule>_pp<ranks>_mbs<mbs>.json
`-- results.csv
```

`results.csv` contains a row for each SPMD rank (e.g., each DP rank) reporting the mean/std iteration time, training throughput in tokens/sec, and per-PP-rank peak memory in GB.

Optional artifact generation flags:

* `--viz` renders the generated pipeline schedule and per-PP-rank DAG IRs under the run directory.
* `--pytorch-profiler --pytorch-profiler-iters <n>` runs extra profiled iterations and writes combined Chrome trace files per SPMD rank; Piper annotates GPU events with DAG IR node labels.

## Development

The GitHub Actions workflow runs the CPU-only pytest suite on pushes and pull requests:

```bash
python -m pytest -m "not gpu" -v test
```

There are currently no pytest tests marked `gpu` under `test/`.
To run the full pytest suite, including any future GPU-marked tests, use:

```bash
python -m pytest -v test
```

For GPU end-to-end validation, run the quickstart examples above on a machine with four visible CUDA devices.
To run all Qwen example schedules, use `examples/run_qwen_examples.py`.

## Citation

If you use Piper in your research, please cite:

```bibtex
@inproceedings{frisella2025piper,
title = {Piper: Towards Flexible Pipeline Parallelism for PyTorch},
author = {Frisella, Megan and Oentoro, Arvin and Gao, Xiangyu and Bernstein, Gilbert and Wang, Stephanie},
booktitle = {Proceedings of the 4th Workshop on Practical Adoption Challenges of ML for Systems},
year = {2025},
publisher = {Association for Computing Machinery},
doi = {10.1145/3766882.3767187},
url = {https://doi.org/10.1145/3766882.3767187}
}
```
Loading
Loading