Skip to content

Commit c0dfb01

Browse files
authored
Merge branch 'main' into sphinx-tv-tutorial
2 parents 069e507 + 77aec05 commit c0dfb01

26 files changed

+1638
-69
lines changed

.github/scripts/docathon-label-sync.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ def main():
2525
issue_number = int(re.findall(r'#(\d{1,5})', pull_request_body)[0])
2626
issue = repo.get_issue(issue_number)
2727
issue_labels = issue.labels
28-
docathon_label_present = any(label.name == 'docathon-h1-2023' for label in issue_labels)
28+
docathon_label_present = any(label.name == 'docathon-h2-2023' for label in issue_labels)
2929

3030
# if the issue has a docathon label, add all labels from the issue to the PR.
3131
if not docathon_label_present:
32-
print("The 'docathon-h1-2023' label is not present in the issue.")
32+
print("The 'docathon-h2-2023' label is not present in the issue.")
3333
return
3434
pull_request_labels = pull_request.get_labels()
3535
issue_label_names = [label.name for label in issue_labels]

.github/workflows/docathon-assign.yml

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,8 @@ jobs:
99
assign:
1010
runs-on: ubuntu-latest
1111
steps:
12-
- name: Install Dependencies
13-
uses: actions/setup-node@v3
14-
with:
15-
node-version: '18'
16-
- name: Install @octokit/core
17-
run: |
18-
npm i @octokit/core @octokit/rest
1912
- name: Check for "/assigntome" in comment
20-
uses: actions/github-script@v4
13+
uses: actions/github-script@v6
2114
env:
2215
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2316
with:
@@ -27,39 +20,39 @@ jobs:
2720
if (assignRegex.test(issueComment)) {
2821
const assignee = context.payload.comment.user.login;
2922
const issueNumber = context.payload.issue.number;
30-
const { Octokit } = require("@octokit/rest");
31-
const octokit = new Octokit({
32-
auth: process.env.GITHUB_TOKEN,
33-
});
34-
const { data: issue } = await octokit.issues.get({
35-
owner: context.repo.owner,
36-
repo: context.repo.repo,
37-
issue_number: issueNumber
38-
});
39-
const hasLabel = issue.labels.some(label => label.name === 'docathon-h1-2023');
23+
try {
24+
const { data: issue } = await github.rest.issues.get({
25+
owner: context.repo.owner,
26+
repo: context.repo.repo,
27+
issue_number: issueNumber
28+
});
29+
const hasLabel = issue.labels.some(label => label.name === 'docathon-h2-2023');
4030
if (hasLabel) {
4131
if (issue.assignee !== null) {
42-
await octokit.issues.createComment({
32+
await github.rest.issues.createComment({
4333
owner: context.repo.owner,
4434
repo: context.repo.repo,
4535
issue_number: issueNumber,
46-
body: "The issue is already assigned. Please pick an opened and unnasigned issue with the [docathon-h1-2023 label](https://github.com/pytorch/tutorials/issues?q=is%3Aopen+is%3Aissue+label%3Adocathon-h1-2023)."
36+
body: "The issue is already assigned. Please pick an opened and unnasigned issue with the [docathon-h2-2023 label](https://github.com/pytorch/pytorch/issues?q=is%3Aopen+is%3Aissue+label%3Adocathon-h2-2023)."
4737
});
4838
} else {
49-
octokit.issues.addAssignees({
39+
await github.rest.issues.addAssignees({
5040
owner: context.repo.owner,
5141
repo: context.repo.repo,
5242
issue_number: issueNumber,
5343
assignees: [assignee]
5444
});
5545
}
5646
} else {
57-
const commmentMessage = "This issue does not have the correct label. Please pick an opened and unnasigned issue with the [docathon-h1-2023 label](https://github.com/pytorch/tutorials/issues?q=is%3Aopen+is%3Aissue+label%3Adocathon-h1-2023)."
58-
await octokit.issues.createComment({
47+
const commmentMessage = "This issue does not have the correct label. Please pick an opened and unnasigned issue with the [docathon-h2-2023 label](https://github.com/pytorch/pytorch/issues?q=is%3Aopen+is%3Aissue+label%3Adocathon-h2-2023)."
48+
await github.rest.issues.createComment({
5949
owner: context.repo.owner,
6050
repo: context.repo.repo,
6151
issue_number: issueNumber,
6252
body: commmentMessage
6353
});
54+
}
55+
} catch (error) {
56+
console.error(error);
6457
}
6558
}

.jenkins/validate_tutorials_built.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"intermediate_source/parametrizations",
2727
"intermediate_source/mnist_train_nas", # used by ax_multiobjective_nas_tutorial.py
2828
"intermediate_source/fx_conv_bn_fuser",
29+
"intermediate_source/_torch_export_nightly_tutorial", # does not work on release
2930
"advanced_source/super_resolution_with_onnxruntime",
3031
"advanced_source/ddp_pipeline", # requires 4 gpus
3132
"prototype_source/fx_graph_mode_ptq_dynamic",

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,16 @@ All the tutorials are now presented as sphinx style documentation at:
55

66
## [https://pytorch.org/tutorials](https://pytorch.org/tutorials)
77

8+
# Asking a question
89

10+
If you have a question about a tutorial, post in https://dev-discuss.pytorch.org/ rather than creating an issue in this repo. Your question will be answered much faster on the dev-discuss forum.
11+
12+
# Submitting an issue
13+
14+
You can submit the following types of issues:
15+
16+
* Feature request - request a new tutorial to be added. Please explain why this tutorial is needed and how it demonstrates PyTorch value.
17+
* Bug report - report a failiure or outdated information in an existing tutorial. When submitting a bug report, please run: `python3 -m torch.utils.collect_env` to get information about your environment and add the output to the bug report.
918

1019
# Contributing
1120

advanced_source/static_quantization_tutorial.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ to enable quantization:
5959
- Replace ReLU6 with ReLU
6060

6161
Note: this code is taken from
62-
`here <https://github.com/pytorch/vision/blob/master/torchvision/models/mobilenet.py>`_.
62+
`here <https://github.com/pytorch/vision/blob/main/torchvision/models/mobilenetv2.py>`_.
6363

6464
.. code:: python
6565

advanced_source/super_resolution_with_onnxruntime.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
.. code-block:: bash
2727
2828
%%bash
29-
pip install onnxruntime
29+
pip install onnx onnxruntime
3030
3131
ONNX Runtime recommends using the latest stable runtime for PyTorch.
3232

beginner_source/blitz/autograd_tutorial.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,4 @@
321321
#
322322
# - `In-place operations & Multithreaded Autograd <https://pytorch.org/docs/stable/notes/autograd.html>`__
323323
# - `Example implementation of reverse-mode autodiff <https://colab.research.google.com/drive/1VpeE6UvEPRz9HmsHh1KS0XxXjYu533EC>`__
324+
# - `Video: PyTorch Autograd Explained - In-depth Tutorial <https://www.youtube.com/watch?v=MswxJw-8PvE>`__

beginner_source/introyt/tensors_deeper_tutorial.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@
378378
#
379379
# - The multiplication operation that created ``b`` was
380380
# broadcast over every “layer” of ``a``.
381-
# - For ``c``, the operation was broadcast over ever layer and row of
381+
# - For ``c``, the operation was broadcast over every layer and row of
382382
# ``a`` - every 3-element column is identical.
383383
# - For ``d``, we switched it around - now every *row* is identical,
384384
# across layers and columns.

conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ def reset_seeds(gallery_conf, fname):
106106
'first_notebook_cell': ("# For tips on running notebooks in Google Colab, see\n"
107107
"# https://pytorch.org/tutorials/beginner/colab\n"
108108
"%matplotlib inline"),
109-
'reset_modules': (reset_seeds)
109+
'reset_modules': (reset_seeds),
110+
'ignore_pattern': r'_torch_export_nightly_tutorial.py'
110111
}
111112

112113
if os.getenv('GALLERY_PATTERN'):

en-wordlist.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ CPUs
5555
CPython
5656
CUDA
5757
Caffe
58+
callable's
5859
Captum
5960
Captum's
6061
CartPole
@@ -75,6 +76,8 @@ DQN
7576
DataPipe
7677
DataPipes
7778
DataLoaders
79+
Decompositions
80+
decompositions
7881
DeepMind
7982
DeiT
8083
DenseNet
@@ -164,6 +167,8 @@ ONNX Runtime
164167
ONNX Script
165168
OpenAI
166169
OpenMP
170+
Opset
171+
opset
167172
Ornstein
168173
OU
169174
PIL

intermediate_source/FSDP_adavnced_tutorial.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ summarization using UncycloHow dataset. The main focus of this tutorial is to
7474
highlight different available features in FSDP that are helpful for training
7575
large scale model above 3B parameters. Also, we cover specific features for
7676
Transformer based models. The code for this tutorial is available in `Pytorch
77-
Examples
78-
<https://github.com/HamidShojanazeri/examples/tree/FSDP_example/distributed/FSDP/>`__.
77+
examples
78+
<https://github.com/pytorch/examples/tree/main/distributed/FSDP/>`__.
7979

8080

8181
*Setup*
@@ -97,13 +97,13 @@ Please create a `data` folder, download the UncycloHow dataset from `wikihowAll.csv
9797
`wikihowSep.cs <https://ucsb.app.box.com/s/7yq601ijl1lzvlfu4rjdbbxforzd2oag>`__,
9898
and place them in the `data` folder. We will use the wikihow dataset from
9999
`summarization_dataset
100-
<https://github.com/HamidShojanazeri/examples/blob/FSDP_example/distributed/FSDP/summarization_dataset.py>`__.
100+
<https://github.com/pytorch/examples/blob/main/distributed/FSDP/summarization_dataset.py>`__.
101101

102102
Next, we add the following code snippets to a Python script “T5_training.py”.
103103

104104
.. note::
105105
The full source code for this tutorial is available in `PyTorch examples
106-
<https://github.com/HamidShojanazeri/examples/tree/FSDP_example/distributed/FSDP>`__.
106+
<https://github.com/pytorch/examples/tree/main/distributed/FSDP/>`__.
107107

108108
1.3 Import necessary packages:
109109

intermediate_source/FSDP_tutorial.rst

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Getting Started with Fully Sharded Data Parallel(FSDP)
88

99
Training AI models at a large scale is a challenging task that requires a lot of compute power and resources.
1010
It also comes with considerable engineering complexity to handle the training of these very large models.
11-
`Pytorch FSDP <https://pytorch.org/blog/introducing-pytorch-fully-sharded-data-parallel-api/>`__, released in PyTorch 1.11 makes this easier.
11+
`PyTorch FSDP <https://pytorch.org/blog/introducing-pytorch-fully-sharded-data-parallel-api/>`__, released in PyTorch 1.11 makes this easier.
1212

1313
In this tutorial, we show how to use `FSDP APIs <https://pytorch.org/docs/1.11/fsdp.html>`__, for simple MNIST models that can be extended to other larger models such as `HuggingFace BERT models <https://huggingface.co/blog/zero-deepspeed-fairscale>`__,
1414
`GPT 3 models up to 1T parameters <https://pytorch.medium.com/training-a-1-trillion-parameter-model-with-pytorch-fully-sharded-data-parallel-on-aws-3ac13aa96cff>`__ . The sample DDP MNIST code has been borrowed from `here <https://github.com/yqhu/mnist_examples>`__.
@@ -18,7 +18,7 @@ How FSDP works
1818
--------------
1919
In `DistributedDataParallel <https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html>`__, (DDP) training, each process/ worker owns a replica of the model and processes a batch of data, finally it uses all-reduce to sum up gradients over different workers. In DDP the model weights and optimizer states are replicated across all workers. FSDP is a type of data parallelism that shards model parameters, optimizer states and gradients across DDP ranks.
2020

21-
FSDP GPU memory footprint would be smaller than DDP across all workers. This makes the training of some very large models feasible and helps to fit larger models or batch sizes for our training job. This would come with the cost of increased communication volume. The communication overhead is reduced by internal optimizations like communication and computation overlapping.
21+
When training with FSDP, the GPU memory footprint is smaller than when training with DDP across all workers. This makes the training of some very large models feasible by allowing larger models or batch sizes to fit on device. This comes with the cost of increased communication volume. The communication overhead is reduced by internal optimizations like overlapping communication and computation.
2222

2323
.. figure:: /_static/img/distributed/fsdp_workflow.png
2424
:width: 100%
@@ -27,7 +27,7 @@ FSDP GPU memory footprint would be smaller than DDP across all workers. This mak
2727

2828
FSDP Workflow
2929

30-
At high level FSDP works as follow:
30+
At a high level FSDP works as follow:
3131

3232
*In constructor*
3333

@@ -48,11 +48,11 @@ At high level FSDP works as follow:
4848

4949
How to use FSDP
5050
--------------
51-
Here we use a toy model to run training on MNIST dataset for demonstration purposes. Similarly the APIs and logic can be applied to larger models for training.
51+
Here we use a toy model to run training on the MNIST dataset for demonstration purposes. The APIs and logic can be applied to training larger models as well.
5252

5353
*Setup*
5454

55-
1.1 Install Pytorch along with Torchvision
55+
1.1 Install PyTorch along with Torchvision
5656

5757
.. code-block:: bash
5858
@@ -139,7 +139,7 @@ We add the following code snippets to a python script “FSDP_mnist.py”.
139139
output = F.log_softmax(x, dim=1)
140140
return output
141141
142-
2.2 define a train function
142+
2.2 Define a train function
143143

144144
.. code-block:: python
145145
@@ -189,7 +189,7 @@ We add the following code snippets to a python script “FSDP_mnist.py”.
189189
190190
2.4 Define a distributed train function that wraps the model in FSDP
191191

192-
**Note: to save the FSDP model, we need to call the state_dict on each rank then on Rank 0 save the overall states. This is only available in Pytorch nightlies, current Pytorch release is 1.11 at the moment.**
192+
**Note: to save the FSDP model, we need to call the state_dict on each rank then on Rank 0 save the overall states.**
193193

194194
.. code-block:: python
195195
@@ -250,7 +250,6 @@ We add the following code snippets to a python script “FSDP_mnist.py”.
250250
if args.save_model:
251251
# use a barrier to make sure training is done on all ranks
252252
dist.barrier()
253-
# state_dict for FSDP model is only available on Nightlies for now
254253
states = model.state_dict()
255254
if rank == 0:
256255
torch.save(states, "mnist_cnn.pt")
@@ -259,7 +258,7 @@ We add the following code snippets to a python script “FSDP_mnist.py”.
259258
260259
261260
262-
2.5 Finally parsing the arguments and setting the main function
261+
2.5 Finally parse the arguments and set the main function
263262

264263
.. code-block:: python
265264
@@ -319,7 +318,7 @@ Alternatively, we will look at adding the fsdp_auto_wrap_policy next and will di
319318
)
320319
)
321320
322-
Following is the peak memory usage from FSDP MNIST training on g4dn.12.xlarge AWS EC2 instance with 4 gpus captured from Pytorch Profiler.
321+
The following is the peak memory usage from FSDP MNIST training on g4dn.12.xlarge AWS EC2 instance with 4 GPUs captured from PyTorch Profiler.
323322

324323

325324
.. figure:: /_static/img/distributed/FSDP_memory.gif
@@ -329,7 +328,7 @@ Following is the peak memory usage from FSDP MNIST training on g4dn.12.xlarge AW
329328

330329
FSDP Peak Memory Usage
331330

332-
*Applying fsdp_auto_wrap_policy* in FSDP otherwise, FSDP will put the entire model in one FSDP unit, which will reduce computation efficiency and memory efficiency.
331+
Applying *fsdp_auto_wrap_policy* in FSDP otherwise, FSDP will put the entire model in one FSDP unit, which will reduce computation efficiency and memory efficiency.
333332
The way it works is that, suppose your model contains 100 Linear layers. If you do FSDP(model), there will only be one FSDP unit which wraps the entire model.
334333
In that case, the allgather would collect the full parameters for all 100 linear layers, and hence won't save CUDA memory for parameter sharding.
335334
Also, there is only one blocking allgather call for the all 100 linear layers, there will not be communication and computation overlapping between layers.
@@ -354,7 +353,7 @@ Finding an optimal auto wrap policy is challenging, PyTorch will add auto tuning
354353
model = FSDP(model,
355354
fsdp_auto_wrap_policy=my_auto_wrap_policy)
356355
357-
Applying the FSDP_auto_wrap_policy, the model would be as follows:
356+
Applying the fsdp_auto_wrap_policy, the model would be as follows:
358357

359358
.. code-block:: bash
360359
@@ -381,7 +380,7 @@ Applying the FSDP_auto_wrap_policy, the model would be as follows:
381380
382381
CUDA event elapsed time on training loop 41.89130859375sec
383382
384-
Following is the peak memory usage from FSDP with auto_wrap policy of MNIST training on g4dn.12.xlarge AWS EC2 instance with 4 gpus captured from Pytorch Profiler.
383+
The following is the peak memory usage from FSDP with auto_wrap policy of MNIST training on a g4dn.12.xlarge AWS EC2 instance with 4 GPUs captured from PyTorch Profiler.
385384
It can be observed that the peak memory usage on each device is smaller compared to FSDP without auto wrap policy applied, from ~75 MB to 66 MB.
386385
387386
.. figure:: /_static/img/distributed/FSDP_autowrap.gif
@@ -391,11 +390,11 @@ It can be observed that the peak memory usage on each device is smaller compared
391390
392391
FSDP Peak Memory Usage using Auto_wrap policy
393392
394-
*CPU Off-loading*: In case the model is very large that even with FSDP wouldn't fit into gpus, then CPU offload can be helpful here.
393+
*CPU Off-loading*: In case the model is very large that even with FSDP wouldn't fit into GPUs, then CPU offload can be helpful here.
395394
396395
Currently, only parameter and gradient CPU offload is supported. It can be enabled via passing in cpu_offload=CPUOffload(offload_params=True).
397396
398-
Note that this currently implicitly enables gradient offloading to CPU in order for params and grads to be on the same device to work with the optimizer. This API is subject to change. Default is None in which case there will be no offloading.
397+
Note that this currently implicitly enables gradient offloading to CPU in order for params and grads to be on the same device to work with the optimizer. This API is subject to change. The default is None in which case there will be no offloading.
399398
400399
Using this feature may slow down the training considerably, due to frequent copying of tensors from host to device, but it could help improve memory efficiency and train larger scale models.
401400
@@ -409,7 +408,7 @@ In 2.4 we just add it to the FSDP wrapper
409408
cpu_offload=CPUOffload(offload_params=True))
410409
411410
412-
Compare it with DDP, if in 2.4 we just normally wrap the model in ddp, saving the changes in “DDP_mnist.py”.
411+
Compare it with DDP, if in 2.4 we just normally wrap the model in DPP, saving the changes in “DDP_mnist.py”.
413412
414413
.. code-block:: python
415414
@@ -423,7 +422,7 @@ Compare it with DDP, if in 2.4 we just normally wrap the model in ddp, saving th
423422
424423
CUDA event elapsed time on training loop 39.77766015625sec
425424
426-
Following is the peak memory usage from DDP MNIST training on g4dn.12.xlarge AWS EC2 instance with 4 gpus captured from Pytorch profiler.
425+
The following is the peak memory usage from DDP MNIST training on g4dn.12.xlarge AWS EC2 instance with 4 GPUs captured from PyTorch profiler.
427426
428427
.. figure:: /_static/img/distributed/DDP_memory.gif
429428
:width: 100%
@@ -434,8 +433,8 @@ Following is the peak memory usage from DDP MNIST training on g4dn.12.xlarge AWS
434433
435434
436435
Considering the toy example and tiny MNIST model we defined here, we can observe the difference between peak memory usage of DDP and FSDP.
437-
In DDP each process holds a replica of the model, so the memory footprint is higher compared to FSDP that shards the model parameter, optimizer states and gradients over DDP ranks.
436+
In DDP each process holds a replica of the model, so the memory footprint is higher compared to FSDP which shards the model parameters, optimizer states and gradients over DDP ranks.
438437
The peak memory usage using FSDP with auto_wrap policy is the lowest followed by FSDP and DDP.
439438
440-
Also, looking at timings, considering the small model and running the training on a single machine, FSDP with/out auto_wrap policy performed almost as fast as DDP.
439+
Also, looking at timings, considering the small model and running the training on a single machine, FSDP with and without auto_wrap policy performed almost as fast as DDP.
441440
This example does not represent most of the real applications, for detailed analysis and comparison between DDP and FSDP please refer to this `blog post <https://pytorch.medium.com/6c8da2be180d>`__ .

0 commit comments

Comments
 (0)