PoC for conserving old links
Author: sgugger
Pull request: yes

# What does this PR do?

The PR evolved to having a little compact section for old links, see this comment for a demo:
https://github.com/huggingface/transformers/pull/14754#issuecomment-995067459

----------------

This follows up from a [#14753 comment](https://github.com/huggingface/transformers/pull/14753#discussion_r767974738) to deal with old links without leaving lots of empty subsections. It just replaces it by an anchor which will make the link not 404 and the text just above tells the user to checkout the DeepSpeed page which contains the same information.

I'll treat the other links the same way if this is accepted.

Comments:
so where can I see it rendered?

in the past it was possible to see the doc as it was built on CI - I don't seem to be able to find the same in this new incarnation. 

Tested it manually by saving the html and editing it as you proposed. It's probably safe to assume everybody uses modern browsers these days.

So you propose to break the anchor links and the only backward link support is to point a user to a new document where all sections got moved to and let them hunt down the actual section they were after, is that correct?



As stated in the internal slack, the ability so see the doc rendered in a PR is still a work in progress, you can see where the link would point on the Markdown [here](https://github.com/huggingface/transformers/blob/79817836add2334e6b1105be2c4cb774a3390362/docs/source/main_classes/trainer.mdx#deepspeed-installation).

> So you propose to break the anchor links

I don't see which link is broken, could you tell me?

> the only backward link support is to point a user to a new document where all sections got moved to and let them hunt down the actual section they were after, is that correct

Yes, the user will have something to do in all cases, and the [doc](https://huggingface.co/docs/transformers/main_classes/deepspeed) clearly show the Table of Contents on the right, so I don't think it will be too hard. We don't even know if there are such links with anchor in the wild, so I think this is enough support.

> As stated in the internal slack, the ability so see the doc rendered in a PR is still a work in progress, you can see where the link would point on the Markdown [here](https://github.com/huggingface/transformers/blob/79817836add2334e6b1105be2c4cb774a3390362/docs/source/main_classes/trainer.mdx#deepspeed-installation).

Right! Thank you!

> > So you propose to break the anchor links
> 
> I don't see which link is broken, could you tell me?

all the links from the right section in the old document to that exact section in the new document.
 
> > the only backward link support is to point a user to a new document where all sections got moved to and let them hunt down the actual section they were after, is that correct
> 
> Yes, the user will have something to do in all cases, and the [doc](https://huggingface.co/docs/transformers/main_classes/deepspeed) clearly show the Table of Contents on the right, so I don't think it will be too hard. We don't even know if there are such links with anchor in the wild, so I think this is enough support.

I know we have such links in the wild and not only in the wild but in our own issues since I used them in various announcements and in issues.

The right hand TOC misses all deeper level sub-sections  than h2. (or is it h3?) So you won't find many sub-sections there. Here is an example: https://huggingface.co/docs/transformers/master/main_classes/deepspeed#zero2-config - it's not in the right-hand menu - and many others items aren't there either. Same for `performance.html`

Again, if as a body we agree that we don't care for such things then your proposed change is perfectly fine.




> all the links from the right section in the old document to that exact section in the new document.

I'm sorry but I don't know what you mean. Can you give me an explicit link that is broken by this change (e.g., will result in a 404)

As for the actual use cases you mention, I don't think the "job" required by the user stumbling on that dead link to scroll or use a search is too much, but let's see what the others think.

I meant broken as in soft 404. Where I wrote something like:

> to solve this problem see this section https://huggingface.co/docs/transformers/master/main_classes/trainer.html#zero2-config 

and the user, reading this comment later can't get to where I pointed to, because the moved-to section has been removed.

> https://huggingface.co/docs/transformers/master/main_classes/trainer.html#zero2-config

unless i'm mistaken, this link was never valid, because the only doc that was under `/docs/` urls is the new doc and never had any .html suffixes

(you might mean the same URL without the /docs ?)

yes, sorry, I have no way of seeing how the old url was other than searching for old style links in issues, so the original would probably be:

https://huggingface.co/transformers/master/main_classes/trainer.html#zero2-config

thank you for the fix, @julien-c 

I've a possible alternative suggestion of doing the same, while keeping things neat and not losing the redirects, will post one soon.

OK, here is what I propose. At the end of each doc file we will have a neat pile of moved links if any and the original anchors that will take the user to this section. The trainer doc will have be the biggest number of these moved links at the moment.

![snapshot_70](https://user-images.githubusercontent.com/10676103/146245623-31bd10a9-1827-42dd-afc8-adf3faced816.png)

but other files may have small ones here and there as the docs evolve. So this allows us to keep backward compatibility not only for the code but for user browsing experience as well.

I purposefully removed line breaks to keep it compact and still allow the user to quickly find what they are after.

If it resonates here is the html for this file:

```

Sections that were moved:

[ <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-trainer-integration">DeepSpeed</a><a id="deepspeed-trainer-integration"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-installation">Installation</a><a id="deepspeed-installation"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-multi-gpu">Deployment with multiple GPUs</a><a id="deepspeed-multi-gpu"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-one-gpu">Deployment with one GPU</a><a id="deepspeed-one-gpu"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-notebook">Deployment in Notebooks</a><a id="deepspeed-notebook"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-config">Configuration</a><a id="deepspeed-config"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-config-passing">Passing Configuration</a><a id="deepspeed-config-passing"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-config-shared">Shared Configuration</a><a id="deepspeed-config-shared"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero">ZeRO</a><a id="deepspeed-zero"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero2-config">ZeRO-2 Config</a><a id="deepspeed-zero2-config"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero3-config">ZeRO-3 Config</a><a id="deepspeed-zero3-config"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-nvme">NVMe Support</a><a id="deepspeed-nvme"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero2-zero3-performance">ZeRO-2 vs ZeRO-3 Performance</a><a id="deepspeed-zero2-zero3-performance"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero2-example">ZeRO-2 Example</a><a id="deepspeed-zero2-example"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero3-example">ZeRO-3 Example</a><a id="deepspeed-zero3-example"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-optimizer">Optimizer</a><a id="deepspeed-optimizer"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-scheduler">Scheduler</a><a id="deepspeed-scheduler"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-fp32">fp32 Precision</a><a id="deepspeed-fp32"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-amp">Automatic Mixed Precision</a><a id="deepspeed-amp"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-bs">Batch Size</a><a id="deepspeed-bs"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-grad-acc">Gradient Accumulation</a><a id="deepspeed-grad-acc"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-grad-clip">Gradient Clipping</a><a id="deepspeed-grad-clip"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-weight-extraction">Getting The Model Weights Out</a><a id="deepspeed-weight-extraction"></a>
]
```

could use relatively links as well if you prefer.

```
Sections that were moved:

[ <a href="./deepspeed#deepspeed-trainer-integration">DeepSpeed</a><a id="deepspeed-trainer-integration"></a>
| <a href="./deepspeed#deepspeed-installation">Installation</a><a id="deepspeed-installation"></a>
| <a href="./deepspeed#deepspeed-multi-gpu">Deployment with multiple GPUs</a><a id="deepspeed-multi-gpu"></a>
| <a href="./deepspeed#deepspeed-one-gpu">Deployment with one GPU</a><a id="deepspeed-one-gpu"></a>
| <a href="./deepspeed#deepspeed-notebook">Deployment in Notebooks</a><a id="deepspeed-notebook"></a>
| <a href="./deepspeed#deepspeed-config">Configuration</a><a id="deepspeed-config"></a>
| <a href="./deepspeed#deepspeed-config-passing">Passing Configuration</a><a id="deepspeed-config-passing"></a>
| <a href="./deepspeed#deepspeed-config-shared">Shared Configuration</a><a id="deepspeed-config-shared"></a>
| <a href="./deepspeed#deepspeed-zero">ZeRO</a><a id="deepspeed-zero"></a>
| <a href="./deepspeed#deepspeed-zero2-config">ZeRO-2 Config</a><a id="deepspeed-zero2-config"></a>
| <a href="./deepspeed#deepspeed-zero3-config">ZeRO-3 Config</a><a id="deepspeed-zero3-config"></a>
| <a href="./deepspeed#deepspeed-nvme">NVMe Support</a><a id="deepspeed-nvme"></a>
| <a href="./deepspeed#deepspeed-zero2-zero3-performance">ZeRO-2 vs ZeRO-3 Performance</a><a id="deepspeed-zero2-zero3-performance"></a>
| <a href="./deepspeed#deepspeed-zero2-example">ZeRO-2 Example</a><a id="deepspeed-zero2-example"></a>
| <a href="./deepspeed#deepspeed-zero3-example">ZeRO-3 Example</a><a id="deepspeed-zero3-example"></a>
| <a href="./deepspeed#deepspeed-optimizer">Optimizer</a><a id="deepspeed-optimizer"></a>
| <a href="./deepspeed#deepspeed-scheduler">Scheduler</a><a id="deepspeed-scheduler"></a>
| <a href="./deepspeed#deepspeed-fp32">fp32 Precision</a><a id="deepspeed-fp32"></a>
| <a href="./deepspeed#deepspeed-amp">Automatic Mixed Precision</a><a id="deepspeed-amp"></a>
| <a href="./deepspeed#deepspeed-bs">Batch Size</a><a id="deepspeed-bs"></a>
| <a href="./deepspeed#deepspeed-grad-acc">Gradient Accumulation</a><a id="deepspeed-grad-acc"></a>
| <a href="./deepspeed#deepspeed-grad-clip">Gradient Clipping</a><a id="deepspeed-grad-clip"></a>
| <a href="./deepspeed#deepspeed-weight-extraction">Getting The Model Weights Out</a><a id="deepspeed-weight-extraction"></a>
]
```

Except I think the local anchors are wrong here. Let me know if you like it and then I will rewrite those.

Yes, the anchors your proposed Sylvain are wrong, since you used the target anchors instead of the local header anchors. e.g. all of them but one should not start with deepspeed 

i.e. "Deployment in Notebooks" should be anchored locally to "deployment-in-notebooks" and not "deepspeed-notebook", i.e.
```
"<a id="deployment-in-notebooks"></a>" is the correct local anchor.
```

Here is one with local anchors;

```
Sections that were moved:

[ <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-trainer-integration">DeepSpeed</a><a id="deepspeed"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-installation">Installation</a><a id="installation"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-multi-gpu">Deployment with multiple GPUs</a><a id="deployment-with-multiple-gpus"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-one-gpu">Deployment with one GPU</a><a id="deployment-with-one-gpu"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-notebook">Deployment in Notebooks</a><a id="deployment-in-notebooks"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-config">Configuration</a><a id="configuration"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-config-passing">Passing Configuration</a><a id="passing-configuration"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-config-shared">Shared Configuration</a><a id="shared-configuration"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero">ZeRO</a><a id="zero"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero2-config">ZeRO-2 Config</a><a id="zero-2-config"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero3-config">ZeRO-3 Config</a><a id="zero-3-config"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-nvme">NVMe Support</a><a id="nvme-support"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero2-zero3-performance">ZeRO-2 vs ZeRO-3 Performance</a><a id="zero-2-vs-zero-3-performance"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero2-example">ZeRO-2 Example</a><a id="zero-2-example"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-zero3-example">ZeRO-3 Example</a><a id="zero-3-example"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-optimizer">Optimizer</a><a id="optimizer"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-scheduler">Scheduler</a><a id="scheduler"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-fp32">fp32 Precision</a><a id="fp32-precision"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-amp">Automatic Mixed Precision</a><a id="automatic-mixed-precision"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-bs">Batch Size</a><a id="batch-size"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-grad-acc">Gradient Accumulation</a><a id="gradient-accumulation"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-grad-clip">Gradient Clipping</a><a id="gradient-clipping"></a>
| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-weight-extraction">Getting The Model Weights Out</a><a id="getting-the-model-weights-out"></a>
]
```

note myself: converted with:
```
perl -pi -e 'BEGIN { sub convert { $_=lc shift; s/ /-/g; return $_ }} s{\| (.*?)<a id=.(.*?).></a>}{qq[| <a href="https://huggingface.co/docs/transformers/main_classes/deepspeed#$2">$1</a><a id="].convert($1).qq["></a>]}e' fix.html
```

This looks like a nice solution. Feel free to take over my branch and use it! I think you should use local anchors as it would work across versions of the documentation.

And yes I copied the anchors from the deepspeed doc but I see they were different in the Trainer doc, so some of them do need to be updated.

done. and made them relative - good call!

Question: how will rst files be converted?

e.g. currently we have:
```
.. _deepspeed-zero2-config:

ZeRO-2 Config
```
will it become:

a.

```
<h3>ZeRO-2 Config</h3><a id="zero-2-config"></a>| 
```
or b.:
```
<h3>ZeRO-2 Config</h3><a id="deepspeed-zero-2-config"></a>| 
```

i.e. are you going to respect the original rst anchors or switch to md archors which is just based on the header name?


You get both anchors. For instance the section "Deployment with one GPU" has two anchors in the current doc that you can test:
[https://huggingface.co/docs/transformers/main_classes/deepspeed#deployment-with-one-gpu](https://huggingface.co/docs/transformers/main_classes/deepspeed#deployment-with-one-gpu) and [https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-one-gpu](https://huggingface.co/docs/transformers/main_classes/deepspeed#deepspeed-one-gpu).

The first one is generated automatically by the front for each section header and the second is a ref generated by the conversion.

I added a little instruction section for other future renames and moves. Please let me know if it's kosher.