You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today we're building 6 versions for 13 languages (that's 78 builds).
I'm doing some tests on my machine to get an idea:
An HTML build takes 55 s.
A full build (html + text + PDF A4 + PDF letter + epub + texinfo) takes around 21 min, composed of:
1 min for make html composed of:
50 s for sphinx-build
10 s of html archiving
40 s for make text
9 min for the A4 PDF build composed of:
1 min for make latex PAPER=a4
8 min for make all-pdf (in build/latex/) (less if run again, like 1 s if not removing PDFs, or 1 min after removing PDFs). Can be cut down to 6 min with -j 4.
8 min 30 for the letter PDF build, roughly similar to A4 unsurprisingly
1 min for the epub build
1 min 30 s for the texinfo build
So a complete rebuild should take ~27h (on my machine, the server may have a different CPU).
What are the versions of latexmk and xetex that are being used on the build server? The latest versions of those packages are 4.81 (2023-11-06) for latexmk and 0.9999.3 (September 2013) for xetex.
(One comment: IIRC, at least one reason we do full rebuilds of the docs and not just incremental builds was that there were problems when a documentation page was deleted by a change and then would not automatically get deleted on-line. I'm not sure if that still is an issue.)
Are the builds continuously built? if so, I'm wondering what I did to make it slow x2... What I remember is that I needed to remove some pickled doctree cache because of a bug and I know that it might have cause a slowdown but I wouldn't have expected that much of a slowdown since it should only affect the make latex command (possibly) or make html command but not the make all-pdf command...
I should check if we can speed up some macro expansions. I'll also try to build the docs without producing a PDF just to see how long it actually takes. Unfortunately, we cannot switch to pdflatex since the English document requires special unicode characters (for the 're' module... =/)
@jfbu sorry to ping, but this issue/thread may be of interest -- unsure of anything we can do within Sphinx(/CPython's docs) to speed up the LaTeX builds, but you may have some insights?
I have not read the full details. There may be tricks allowing to make only 2 passes in place of 3 sometimes with latex triggered from latexmk. But recently I worked on a lualatex build of a 1800 pages document with lots of pdf inclusions and highlighted code-blocks, output was more than 40M (due to fonts I think of the included pdf's) and each latex pass cost more than 3 minutes on an old 2Ghz single core computer. When I first read the title I thought that a single file took 24h which was really quite spectacular but of course here it is about building many many PDFs are built. I think pdflatex is somewhat faster than xelatex and definitely is faster than lualatex and in some cases with only few Unicode characters to support, it could be option. But that will not be a 10x gain, the most we can hope 2x from this. Usually Latexmk is very good at not making extra builds. But with LaTeX, any change to a section title will cause next time at least 2 passes.
Please correct me if I'm mistaken, but I think that Sphinx multi-page HTML build (and similarly epub, text, ... and texinfo (?)) pipelines can skip a lot of work during builds when only a small number of the source documents have been modified.
Can a LaTeX-to-PDF build process do the same? (in other words: the reprocessing passes after a section title change: do those have to load/parse the entire Python LaTeX docs?)
Can a LaTeX-to-PDF build process do the same? (in other words: the reprocessing passes after a section title change: do those have to load/parse the entire Python LaTeX docs?)
@jayaddison alas, I don't think so. We could imagine Sphinx using \include mechanisms so that at least producing a modified LaTeX file could be localized. But when comes the time of LaTeX-to-PDF, LaTeX will have to redo 100% of its job. We could imagine also producing separate small PDFs but I know of no feasible automated way to merge these small PDFs in such a way that all hyperlinks will work, and that all automated enumeration of figures for example work the same as when doing the single PDF from a single source (whether or not that source is a huge one or a small main file with lots of \include's, which from LaTeX point of view is almost same).
We could imagine also producing separate small PDFs but I know of no feasible automated way to merge these small PDFs in such a way that all hyperlinks will work, and that all automated enumeration of figures for example work the same as when doing the single PDF from a single source
Thanks; that all makes sense. To avoid the problem of "new large paragraph on page five shifts all content from pages 5-300" -- which could happen if the intermediate files were TeX and did not have some kind of hacky force-page-break mechanism -- I think that PDF-per-docname would be the approach (mirroring the html build).
So that brings the PDF-merge problem, and yep, it makes sense that of the few PDF merge tools available, many probably don't retain internal hyperlinks. I'm optimistic that pypdf (coincidental that it's Python) might be able to do this though, based on py-pdf/pypdf#471 (actually about HTML links, but it seems that they take hyperlinks seriously).
Enumerated figures could be more challenging - and perhaps now we're drifting off-topic (although I do think that if we could find a solution here, it might be applicable to this thread's problem statement). Should I start a discussion thread over at sphinx-doc/sphinx?
Should I start a discussion thread over at sphinx-doc/sphinx?
@jayaddison I read a bit more closely some of this thread and indeed it seems we started drifting a bit off-topic and sphinx-doc/sphinx would be a better place for a general issue about faster PDF builds with or without LaTeX. For example I have nil experience with the rinohtype builder not for lack of interest but purely for lack of time. For that very same reason I will not in immediate future be able to contribute much to any such general discussion.
Coming back to this thread I remember a few years back I could set-up the build on RTD of our (Sphinx) own PDF docs in a way which let it make only 2 not 3 passes. Perhaps something like this would be possible here for the Python docs. Some years back I did build them locally from time to time. I must update my hardware first... I would love to discover the joys of multi-threaded builds 😃
Crazy ideas like using Python to build all LaTeX auxiliary files from a Python tool are too crazy: it is impossible to know page numbers in advance and page numbers are the things that change most in the aux files and trigger (via Latexmk usually quasi-optimal decisions) if a re-build is needed. Of course if you do make clean you are in for the full show of many passes.
Also, if latexmk is at version 4.52b or higher (January 2017) LATEXMKOPTS="-xelatex" speeds up PDF builds via XeLateX in case of numerous graphics inclusions.
If you launch via make latexpdf LATEXMKOPTS="-xelatex" (or similar with all-pdf target inside the latex build repertory after make latex) the xelatex builds will get faster. To what extent, I am not sure.
Probably we at Sphinx should have made this default some time ago, perhaps about two years ago or so. The problem is that if you use that -xelatex with an older Latexmk probably it will refuse to build (although it may have gracefully ignored it but I can't test now; the test for all those years was on whether people read our docs 😃 ). I will make a PR at Sphinx.
What are the versions of latexmk and xetex that are being used on the build server? The latest versions of those packages are 4.81 (2023-11-06) for latexmk and 0.9999.3 (September 2013) for xetex.
hugovk@docs:~$ apt-cache policy texlive-xetex
texlive-xetex:
Installed: 2023.20240207-1
Candidate: 2023.20240207-1
Version table:
*** 2023.20240207-1 500
500 http://mirrors.digitalocean.com/ubuntu noble/universe amd64 Packages
100 /var/lib/dpkg/status
hugovk@docs:~$ xetex --version
XeTeX 3.141592653-2.6-0.999995 (TeX Live 2023/Debian)
kpathsea version 6.3.5
Copyright 2023 SIL International, Jonathan Kew and Khaled Hosny.
There is NO warranty. Redistribution of this software is
covered by the terms of both the XeTeX copyright and
the Lesser GNU General Public License.
For more information about these matters, see the file
named COPYING and the XeTeX source.
Primary author of XeTeX: Jonathan Kew.
Compiled with ICU version 74.2; using 74.2
Compiled with zlib version 1.3; using 1.3
Compiled with FreeType2 version 2.13.2; using 2.13.2
Compiled with Graphite2 version 1.3.14; using 1.3.14
Compiled with HarfBuzz version 8.3.0; using 8.3.0
Compiled with libpng version 1.6.43; using 1.6.43
Compiled with pplib version v2.05 less toxic i hope
Compiled with fontconfig version 2.15.0; using 2.15.0
Whilst checking the fix for #186, for the past couple of days I've been keeping an eye on the server build log and top processes (tail -f /var/log/docsbuild/docsbuild.log and top -i -u docsbuild).
Most of the time is spent on the make -C /srv/docsbuild/cpython/Doc ... commands. Here's logs for a single language/version:
When this runs Sphinx, we sometimes get four sphinx-build processes using up to 100% CPU each. This is good, we're making good use of the resources available. (Sometimes there's only 1-2 processes, depending on what part of the build Sphinx is at.)
top - 13:00:14 up 7 days, 14:31, 2 users, load average: 2.73, 1.59, 1.55
Tasks: 175 total, 7 running, 168 sleeping, 0 stopped, 0 zombie
%Cpu(s): 86.5 us, 1.7 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.2 si, 11.6 st
MiB Mem : 7941.4 total, 4206.4 free, 1490.0 used, 2581.0 buff/cache
MiB Swap: 1024.0 total, 1024.0 free, 0.0 used. 6451.3 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
633264 docsbui+ 20 0 133336 118608 5376 R 91.1 1.5 0:22.67 sphinx-build
633365 docsbui+ 20 0 130688 115708 5248 R 88.1 1.4 0:07.73 sphinx-build
633263 docsbui+ 20 0 117020 102752 5376 R 86.8 1.3 0:25.98 sphinx-build
633266 docsbui+ 20 0 135080 120984 5632 R 86.8 1.5 0:20.58 sphinx-build
But most of the time it's running a latex command. These only use CPU, but at least generally use 100%:
top - 13:03:45 up 7 days, 14:34, 2 users, load average: 1.53, 1.99, 1.77
Tasks: 181 total, 2 running, 179 sleeping, 0 stopped, 0 zombie
%Cpu(s): 25.9 us, 0.9 sy, 0.0 ni, 73.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 7941.4 total, 4133.7 free, 1525.6 used, 2618.7 buff/cache
MiB Swap: 1024.0 total, 1024.0 free, 0.0 used. 6415.8 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
637944 docsbui+ 20 0 726692 546544 40048 R 100.0 6.7 0:21.42 xelatex
637946 docsbui+ 20 0 23432 21740 3072 S 4.0 0.3 0:00.82 xdvipdfmx
81398 docsbui+ 20 0 76388 67640 10368 S 0.7 0.8 20:19.58 python
Here's the time between the "Build start"/"Build done" pairs:
table of build times
Start
Language/version
Build
2024-08-14 00:45
pl/3.14
38m
2024-08-14 01:24
ko/3.14
56m
2024-08-14 02:22
ja/3.14
1h 37m
2024-08-14 04:01
it/3.14
36m
2024-08-14 04:39
id/3.14
45m
2024-08-14 05:55
es/3.14
2h 11m
2024-08-14 08:07
en/3.14
35m
2024-08-14 09:07
zh-tw/3.12
1h 39m
2024-08-14 10:47
zh-cn/3.12
1h 23m
2024-08-14 12:12
uk/3.12
3m
2024-08-14 12:17
pt-br/3.12
44m
2024-08-14 13:03
ko/3.12
56m
2024-08-14 14:01
ja/3.12
1h 32m
2024-08-14 15:35
es/3.12
2h 8m
2024-08-14 17:45
zh-tw/3.13
1h 44m
2024-08-14 19:30
zh-cn/3.13
1h 35m
2024-08-14 21:06
uk/3.13
3m
2024-08-14 21:10
tr/3.13
2h 4m
2024-08-14 23:32
en/3.13
38m
2024-08-15 00:11
zh-tw/3.14
1h 46m
2024-08-15 01:59
zh-cn/3.14
1h 36m
2024-08-15 03:37
uk/3.14
3m
2024-08-15 03:42
tr/3.14
1h 58m
2024-08-15 05:42
pt-br/3.14
50m
2024-08-15 06:34
pl/3.14
43m
2024-08-15 07:18
ko/3.14
1h 1m
2024-08-15 08:21
ja/3.14
1h 44m
2024-08-15 10:07
it/3.14
39m
2024-08-15 10:48
id/3.14
49m
2024-08-15 12:10
es/3.14
2h 15m
2024-08-15 14:27
en/3.14
38m
2024-08-15 16:07
zh-tw/3.12
1h 56m
2024-08-15 18:06
zh-cn/3.12
1h 36m
2024-08-15 19:44
uk/3.12
3m
2024-08-15 19:48
tr/3.12
2h 6m
2024-08-15 21:56
pt-br/3.12
43m
2024-08-15 22:41
pl/3.12
38m
2024-08-15 23:21
ko/3.12
55m
We're spending a LOT of time churning out those PDFs: an hour or two per language/version.
The cron triggers at 7 minutes past the hour. If there's a build currently running, the new one just ends.
Suggestion: split HTML and PDF builds
I suggest we have two cron jobs. One that builds only HTML, the other that does everything else except HTML.
We'd allow these to run at the same time. A full HTML batch should be very quick. For example, the Ukrainian build is HTML only and takes 3 minutes. 13 languages x 3 minutes = 39 minutes.
We'd get docs HTML updates out the door quickly: ~30 minutes instead of ~30 hours! I also expect many of the next hourly triggers would not to need to rebuild anything, because there's less likely to be new docs changes after one hour compared to 30 hours.
I expect the other cron job that does non-HTML would still take about as long as now, as it's mostly churning out latex files on a single process. But we're more efficiently using the other CPUs for HTML.
I don't have download numbers for the PDFs etc, but I expect they're used much less than the HTML. And HTML is read live on the web right now, others are downloaded for reference and will (maybe) be re-downloaded at some later date.
In fact, I just spotted that #127 / python/psf-salt#236 said we used to build PDFs daily and the docs hourly. That PR was merged two years ago, shall we go back to this?
I would even suggest building PDFs every 36/48 hours. The main problem with building PDFs less often seems to have been new releases (especially .0) don't have PDF versions at release date, but this seems surmountable.
It seems that we could run multiple latexmk processes for each build (ref: https://tex.stackexchange.com/a/699204) which might improve things -- I'll try and have a look if no one beats me to it.
A
Reacted by Hugo van Kemenade, Manuel Kaufmann and Jean-François B.
It seems that we could run multiple latexmk processes for each build (ref: https://tex.stackexchange.com/a/699204) which might improve things -- I'll try and have a look if no one beats me to it.
Sounds promising. I can not really test, but wouldn't -j option of make (in the builddir) help here?
I tried running directly latexmk as in https://tex.stackexchange.com/a/699204 but on my system it does not exit once job completes one has to hit RET; besides one should not run it directly so I tried adding the & inside the Makefile rule, same issue, then I tried & with make foo.pdf &, make foo2.pdf & again same issue, and finally -j appears to work: make -j all-pdf in the latex builddir.
But here it should be I guess the with the largest .tex files first so make -j library.pdf c-api.pdf reference.pdf <here the others> (in the latex builddir or with -C option) and not this make -j all-pdf I tried.
(I already admitted being on a single core system, so I can not vouch this will use multiple cores in real life).
As per my earlier comment about -xelatex option, see sphinx-doc/sphinx#12636. Best sure way to gain some time is to run the whole build in a TeXLive2019 environment not a TeXLive2024 one. Of course if that is compatible with extras from conf.py (fonts configuration?) which I have not checked here. Core Sphinx (even latest current version) produces exactly same result in a TL2019 based environment as in a TL2024 one.
It turns out we have inadvertently been running the full latexmk process twice for every build, since around 2010. Luckily, this is fixable.
The LaTex build in Sphinx generates a makefile which we use to run latexmk and generate the actual PDFs from the .tex sources that Sphinx creates. In CPython's Doc/Makefile, we call that makefile in a submake: (cd build/latex; make clean && make all-pdf && make FMT=pdf zip bz2).
Considering the generated Makefile at Doc/build/latex/Makefile, the all-pdf target depends on $(ALLPDF), a list of every desired PDF file. The zip and bz2 targets also depend on $(ALLPDF). All three of all-pdf, zip, and bz2 are .PHONY targets, which are evaluated every time make runs. Normally, this wouldn't present an issue, as the zip and bz2 targets depend on $(ALLPDF) rather than all-pdf, so make would know not to rebuild the PDF files. The issue becomes clear with the %.pdf target. By depending on the .PHONY target FORCE_MAKE, PDF files are forcibly regenerated on both invocations of make, bypassing the inbuilt artefact caching.
Resolving this is straightforwards, and I have a branch prepared to open a PR to CPython. EDIT: I have opened the PR at python/cpython#123113.
Sample timings (8 core CPU, via WSL):
Variant
Command
time (real)
Parallel with -xelatex
make -j LATEXMKOPTS="-xelatex" all-pdf && make FMT=pdf zip bz2
13m55s
As above, fixed makefile targets
make -j LATEXMKOPTS="-xelatex" all-pdf && make FMT=pdf zip bz2
5m54s
As above, without -xelatex
make -j all-pdf && make FMT=pdf zip bz2
5m55s
As above, max 12 jobs
make -j12 all-pdf && make FMT=pdf zip bz2
6m4s
I am proposing to use the final option, as whilst not the absolute fastest, it helps to mitigate scheduling problems, and the docs server only has 4 CPU cores, per Hugo's comment. It seems that -xelatex doesn't make a massive difference here.
A
Reacted by Maciej Olko, Hugo van Kemenade and Manuel Kaufmann
Good catch! The blame is on me at sphinx-doc/sphinx@409605d, but to my defence former Makefile did 5 (pdf)latex builds each time. Actually re-reading your post I am wondering if latexmk really triggers again xelatex. It should say something like this (this is an example on a dummy project)
$ make -C _build/latex all-pdf
make : on entre dans le répertoire « /pathto/sphinxtests/12778_box-shadow/_build/latex »
latexmk -pdf -dvi- -ps- 'foo.tex'
Rc files read:
latexmkrc
Latexmk: This is Latexmk, John Collins, 7 Apr. 2024. Version 4.85.
Latexmk: Nothing to do for 'foo.tex'.
Latexmk: All targets (foo.pdf) are up-to-date
make : on quitte le répertoire « /pathto/sphinxtests/12778_box-shadow/_build/latex »
I am proposing to use the final option, as whilst not the absolute fastest, it helps to mitigate scheduling problems, and the docs server only has 4 CPU cores, per Hugo's comment
I think one has to make sure none of the 4 or 5 biggest files end up being handled by same core which may require a more complex layer to first list files as per decreasing filesizes of the .tex and feed them in that order to make as pdf targets.
It seems that -xelatex doesn't make a massive difference here.
Yes Sphinx docs is too optimistic about this. It makes a difference when build documents does a ton of graphics inclusions. Sphinx docs does say it makes a difference in case of tons of graphics inclusions.
If you can build in an environment with a LaTeX distribution based upon TeXLive 2019 you will probably observe 30% or more additional gain. See this comment. I can not guarantee it completely because the comment compared builds on TL2019 and TL2024 and you use a Debian TL2023, so the gain might not be as much (I currently can not test on a TL2023). The PDFs will be exactly identical.
edit: I mean will look and print identical. Perhaps things are different regarding copy-paste from PDF and some other matters.
(I can not quantify at this time if the change from TL2023 to TL2024 induced the major part in slow-down of LaTeX kernel, or if it occurred earlier).
A docker image is available for all TeXLive versions since 2014. The problem is that it contains the full thing which is much much more than what is strictly needed for Sphinx make latexpdf even leaving aside all sources and all documentation. Unfortunately I have personally no experience with this (having multiple TeXLive's on my computer already there), and to start with I have no idea if you can use such a Docker image and if its large size is an impediment (and I have other tasks now).
There is a sphinx-latexpdf Docker image used for our CI, if I knew the recipe I could modify it to use TeXLive2019. And in the process try to use a much smaller part of full TeXLive hence construct a much smaller Docker image. But this is time-consuming task for which I don't have the immediate qualifications.
Update, we've cut the build times by around another third, by cutting about 15h per full build loop through dropping the letter PDF build (and keeping A4 PDF):
It seems we're currently running around 10h 40m for each version -- Python 3.13 hasn't done a full rebuild in a while as the last commit was a fortnight ago (save around a dozen in the last half-hour!). This would be roughly 32 hours for a full rebuild of 3.12--3.14.
Timings:
Start
Version
Language
Build
Reason
2024-09-20 11:07 GMT
3.14
zh-tw
1h 45m
docs
2024-09-20 12:53 GMT
3.14
zh-cn
1h 38m
docs
2024-09-20 14:31 GMT
3.14
uk
4m
docs
2024-09-20 14:35 GMT
3.14
tr
1h 2m
docs
2024-09-20 15:38 GMT
3.14
pt-br
31m
docs
2024-09-20 16:10 GMT
3.14
pl
24m
docs
2024-09-20 16:35 GMT
3.14
ko
35m
docs
2024-09-20 17:10 GMT
3.14
ja
55m
docs
2024-09-20 18:06 GMT
3.14
it
24m
docs
2024-09-20 18:31 GMT
3.14
id
32m
docs
2024-09-20 19:04 GMT
3.14
fr
24m
docs
2024-09-20 19:29 GMT
3.14
es
1h 14m
docs
2024-09-20 20:43 GMT
3.14
en
23m
docs
2024-09-20 21:07 GMT
3.13
zh-cn
1h 48m
translation
2024-09-20 23:24 GMT
3.12
zh-tw
1h 37m
docs
2024-09-21 01:02 GMT
3.12
zh-cn
1h 21m
translation
2024-09-21 02:24 GMT
3.12
uk
3m
docs
2024-09-21 02:28 GMT
3.12
tr
1h 2m
docs
2024-09-21 03:31 GMT
3.12
pt-br
27m
translation
2024-09-21 04:00 GMT
3.12
pl
23m
translation
2024-09-21 04:23 GMT
3.12
ko
30m
docs
2024-09-21 04:53 GMT
3.12
ja
44m
translation
2024-09-21 05:38 GMT
3.12
it
21m
docs
2024-09-21 06:01 GMT
3.12
id
33m
docs
2024-09-21 06:35 GMT
3.12
fr
22m
docs
2024-09-21 06:58 GMT
3.12
es
1h 6m
docs
2024-09-21 08:05 GMT
3.12
en
20m
docs
2024-09-21 08:30 GMT
--FULL-
-BUILD--
21h 23m 31s
-----------
2024-09-21 09:07 GMT
3.14
zh-cn
1h 29m
translation
2024-09-21 10:37 GMT
3.14
uk
4m
translation
2024-09-21 10:41 GMT
3.14
pt-br
29m
translation
2024-09-21 11:11 GMT
3.14
ja
52m
translation
2024-09-21 12:04 GMT
3.13
zh-cn
1h 37m
translation
2024-09-21 13:42 GMT
3.13
uk
4m
translation
2024-09-21 13:46 GMT
3.13
pt-br
43m
translation
2024-09-21 14:30 GMT
3.13
ja
1h 22m
translation
2024-09-21 16:24 GMT
3.12
uk
3m
translation
2024-09-21 16:34 GMT
--FULL-
-BUILD--
7h 27m 6s
-----------
2024-09-21 17:07 GMT
3.14
zh-cn
1h 29m
translation
2024-09-21 18:37 GMT
3.13
zh-cn
1h 37m
translation
2024-09-21 20:48 GMT
--FULL-
-BUILD--
3h 41m 24s
-----------
2024-09-21 21:41 GMT
--FULL-
-BUILD--
34m 43s
-----------
2024-09-21 22:39 GMT
--FULL-
-BUILD--
32m 36s
-----------
2024-09-21 23:39 GMT
--FULL-
-BUILD--
32m 17s
-----------
2024-09-22 00:07 GMT
3.14
pt-br
29m
translation
2024-09-22 00:37 GMT
3.14
ja
53m
translation
2024-09-22 01:31 GMT
3.13
pt-br
43m
translation
2024-09-22 03:41 GMT
3.12
ja
42m
translation
2024-09-22 04:29 GMT
--FULL-
-BUILD--
4h 22m 7s
-----------
2024-09-22 05:07 GMT
3.14
zh-cn
1h 25m
translation
2024-09-22 06:33 GMT
3.14
uk
4m
translation
2024-09-22 06:38 GMT
3.13
zh-cn
1h 36m
translation
2024-09-22 08:15 GMT
3.13
uk
4m
translation
2024-09-22 08:19 GMT
3.13
ja
1h 21m
translation
2024-09-22 10:10 GMT
3.12
uk
3m
translation
2024-09-22 10:19 GMT
--FULL-
-BUILD--
5h 12m 32s
-----------
2024-09-22 11:07 GMT
3.14
zh-cn
1h 27m
translation
2024-09-22 12:35 GMT
3.14
pl
22m
translation
2024-09-22 12:58 GMT
3.13
zh-cn
1h 43m
translation
2024-09-22 14:42 GMT
3.13
pl
36m
translation
2024-09-22 15:49 GMT
3.12
zh-cn
1h 20m
translation
2024-09-22 17:15 GMT
--FULL-
-BUILD--
6h 8m 23s
-----------
2024-09-22 18:07 GMT
3.14
zh-cn
1h 30m
translation
2024-09-22 19:38 GMT
3.13
zh-cn
1h 42m
translation
2024-09-22 21:56 GMT
--FULL-
-BUILD--
3h 49m 44s
-----------
2024-09-22 22:43 GMT
--FULL-
-BUILD--
36m 14s
-----------
2024-09-22 23:38 GMT
3.12
zh-tw
1h 37m
translation
2024-09-23 01:16 GMT
3.12
ja
43m
translation
2024-09-23 02:05 GMT
--FULL-
-BUILD--
2h 58m 32s
-----------
2024-09-23 02:07 GMT
3.14
zh-tw
1h 42m
translation
2024-09-23 03:50 GMT
3.14
zh-cn
1h 25m
translation
2024-09-23 05:15 GMT
3.14
pt-br
28m
translation
2024-09-23 05:44 GMT
3.14
ja
59m
translation
2024-09-23 06:44 GMT
3.13
zh-tw
1h 57m
translation
2024-09-23 08:42 GMT
3.13
zh-cn
1h 38m
translation
2024-09-23 10:21 GMT
3.13
uk
4m
translation
2024-09-23 10:26 GMT
3.13
pt-br
45m
translation
2024-09-23 11:11 GMT
3.13
ja
1h 25m
translation
2024-09-23 13:07 GMT
3.12
zh-tw
1h 44m
translation
2024-09-23 14:52 GMT
3.12
zh-cn
1h 26m
docs
2024-09-23 16:19 GMT
3.12
uk
3m
translation
2024-09-23 16:23 GMT
3.12
tr
1h 2m
docs
2024-09-23 17:26 GMT
3.12
pt-br
29m
docs
2024-09-23 17:56 GMT
3.12
pl
In progress...
docs
(reason is 'translation' if an updated translation caused the rebuild rather than updated docs, and 'FULL BUILD' captures the end of a full rebuild loop. The loops that are 'empty' but around 30m long attempt a build of fr/3.13 and fail, see #187)
I suggest that we close this issue in favour of #209, now that python/docs-community#131 has been implemented. The non-HTML archive builds still take a while, but it's a manageable duration and we now have the luxury of adjusting the frequency of those builds to e.g. once every two days rather than daily.
Thank you to everyone involved for the help in reducing build times, we have made significant strides here in a challenging problem straddling multiple teams, projects, and repos.
Activity
willingc commentedon Dec 12, 2023
@hugovk @JulienPalard What are the next steps needed for this?
JulienPalard commentedon Dec 12, 2023
I see the last build on
Last updated on Dec 11, 2023 (04:33 UTC), so the build is running, still slow though.hugovk commentedon Dec 12, 2023
It now says
Last updated on Dec 12, 2023 (08:00 UTC)on https://docs.python.org/3/If it took 27.5 hours, what language/versions has it been building to delay it?
There have been changes to 3.11-3.13 in the past day, but a week or more for 3.10 and older.
JulienPalard commentedon Dec 13, 2023
Since we stopped rebuilding when it's not needed, we're maintaining a file with some infos:
see file
it's not that readable but may help a bit.
I can paste some logs here:
view file
so yes, there's still almost 24h between any builds.
In 14 days we've seen only 45 build being skipped vs 449 rebuilds being needed:
is is partly due to some translation repos having a cron commiting every day (like transifex pulls) even if there's no new translations in the files.
But the root cause of slow build time is probably more #169 (comment) (latexmk running xelatex in a loop until the result stop changing).
@ewdurbin what "CPU" do we have on the machine? I don't see usefull info on
/proc/cpuinfo.willingc commentedon Dec 14, 2023
How important are the latex builds?
We may want to look at additional ways of optimizing the latex builds. https://blog.martisak.se/2023/10/01/compiling/
JulienPalard commentedon Dec 14, 2023
PDF builds are based on LaTeX builds.
When PDFs are unavailable we have user complaints (typically on docs@).
willingc commentedon Dec 14, 2023
Yeah, we definitely need PDFs.
I wonder if it makes sense to try building PDF with an alternate tool,
such as pyppeteer which is used by Jupyter book. https://jupyterbook.org/en/stable/advanced/pdf.html#build-a-pdf-from-your-book-htmlplaywright-python.willingc commentedon Dec 14, 2023
Shotscraper could be another approach: https://shot-scraper.datasette.io/en/stable/pdf.html
methane commentedon Dec 14, 2023
PDF shoud provide table of contents and index.
So ePub is better than html for converting into PDF.
But I don't know good tool to convert ePub to PDF.
Maybe, Calibre?
m-aciek commentedon Dec 14, 2023
What are the versions of latexmk and xetex that are being used on the build server? The latest versions of those packages are 4.81 (2023-11-06) for latexmk and 0.9999.3 (September 2013) for xetex.
JulienPalard commentedon Dec 14, 2023
ned-deily commentedon Apr 29, 2024
(One comment: IIRC, at least one reason we do full rebuilds of the docs and not just incremental builds was that there were problems when a documentation page was deleted by a change and then would not automatically get deleted on-line. I'm not sure if that still is an issue.)
hugovk commentedon Jul 15, 2024
I set up a repo to monitor the build times: https://github.com/hugovk/last-updated/actions/runs/9934564679/job/27439140210
And it's now taking 40-50 hours between version builds:
https://github.com/hugovk/last-updated/actions/runs/9934564679/job/27439140210#step:6:14
picnixz commentedon Jul 15, 2024
Are the builds continuously built? if so, I'm wondering what I did to make it slow x2... What I remember is that I needed to remove some pickled doctree cache because of a bug and I know that it might have cause a slowdown but I wouldn't have expected that much of a slowdown since it should only affect the
make latexcommand (possibly) ormake htmlcommand but not themake all-pdfcommand...I should check if we can speed up some macro expansions. I'll also try to build the docs without producing a PDF just to see how long it actually takes. Unfortunately, we cannot switch to pdflatex since the English document requires special unicode characters (for the 're' module... =/)
AA-Turner commentedon Jul 18, 2024
@jfbu sorry to ping, but this issue/thread may be of interest -- unsure of anything we can do within Sphinx(/CPython's docs) to speed up the LaTeX builds, but you may have some insights?
A
jfbu commentedon Jul 18, 2024
I have not read the full details. There may be tricks allowing to make only 2 passes in place of 3 sometimes with latex triggered from latexmk. But recently I worked on a lualatex build of a 1800 pages document with lots of pdf inclusions and highlighted code-blocks, output was more than 40M (due to fonts I think of the included pdf's) and each latex pass cost more than 3 minutes on an old 2Ghz single core computer. When I first read the title I thought that a single file took 24h which was really quite spectacular but of course here it is about building many many PDFs are built. I think pdflatex is somewhat faster than xelatex and definitely is faster than lualatex and in some cases with only few Unicode characters to support, it could be option. But that will not be a 10x gain, the most we can hope 2x from this. Usually Latexmk is very good at not making extra builds. But with LaTeX, any change to a section title will cause next time at least 2 passes.
jayaddison commentedon Jul 18, 2024
Please correct me if I'm mistaken, but I think that Sphinx multi-page HTML build (and similarly
epub,text, ... andtexinfo(?)) pipelines can skip a lot of work during builds when only a small number of the source documents have been modified.Can a LaTeX-to-PDF build process do the same? (in other words: the reprocessing passes after a section title change: do those have to load/parse the entire Python LaTeX docs?)
jfbu commentedon Jul 18, 2024
@jayaddison alas, I don't think so. We could imagine Sphinx using
\includemechanisms so that at least producing a modified LaTeX file could be localized. But when comes the time of LaTeX-to-PDF, LaTeX will have to redo 100% of its job. We could imagine also producing separate small PDFs but I know of no feasible automated way to merge these small PDFs in such a way that all hyperlinks will work, and that all automated enumeration of figures for example work the same as when doing the single PDF from a single source (whether or not that source is a huge one or a small main file with lots of\include's, which from LaTeX point of view is almost same).jayaddison commentedon Jul 18, 2024
Thanks; that all makes sense. To avoid the problem of "new large paragraph on page five shifts all content from pages 5-300" -- which could happen if the intermediate files were TeX and did not have some kind of hacky force-page-break mechanism -- I think that PDF-per-docname would be the approach (mirroring the
htmlbuild).So that brings the PDF-merge problem, and yep, it makes sense that of the few PDF merge tools available, many probably don't retain internal hyperlinks. I'm optimistic that
pypdf(coincidental that it's Python) might be able to do this though, based on py-pdf/pypdf#471 (actually about HTML links, but it seems that they take hyperlinks seriously).Enumerated figures could be more challenging - and perhaps now we're drifting off-topic (although I do think that if we could find a solution here, it might be applicable to this thread's problem statement). Should I start a discussion thread over at
sphinx-doc/sphinx?jfbu commentedon Jul 18, 2024
@jayaddison I read a bit more closely some of this thread and indeed it seems we started drifting a bit off-topic and
sphinx-doc/sphinxwould be a better place for a general issue about faster PDF builds with or without LaTeX. For example I have nil experience with the rinohtype builder not for lack of interest but purely for lack of time. For that very same reason I will not in immediate future be able to contribute much to any such general discussion.Coming back to this thread I remember a few years back I could set-up the build on RTD of our (Sphinx) own PDF docs in a way which let it make only 2 not 3 passes. Perhaps something like this would be possible here for the Python docs. Some years back I did build them locally from time to time. I must update my hardware first... I would love to discover the joys of multi-threaded builds 😃
Crazy ideas like using Python to build all LaTeX auxiliary files from a Python tool are too crazy: it is impossible to know page numbers in advance and page numbers are the things that change most in the aux files and trigger (via Latexmk usually quasi-optimal decisions) if a re-build is needed. Of course if you do
make cleanyou are in for the full show of many passes.jfbu commentedon Jul 21, 2024
Hello all, I suddenly realize I never pointed out that info in Sphinx docs:
If you launch via
make latexpdf LATEXMKOPTS="-xelatex"(or similar withall-pdftarget inside the latex build repertory aftermake latex) thexelatexbuilds will get faster. To what extent, I am not sure.Probably we at Sphinx should have made this default some time ago, perhaps about two years ago or so. The problem is that if you use that
-xelatexwith an older Latexmk probably it will refuse to build (although it may have gracefully ignored it but I can't test now; the test for all those years was on whether people read our docs 😃 ). I will make a PR at Sphinx.hugovk commentedon Aug 16, 2024
The new Ubuntu 24.04 server (python/psf-salt#421) has:
And it has 4 CPUs with 8 GB RAM:
hugovk commentedon Aug 16, 2024
Here's some observations and a suggestion.
Observations
Whilst checking the fix for #186, for the past couple of days I've been keeping an eye on the server build log and top processes (
tail -f /var/log/docsbuild/docsbuild.logandtop -i -u docsbuild).Most of the time is spent on the
make -C /srv/docsbuild/cpython/Doc ...commands. Here's logs for a single language/version:logs
When this runs Sphinx, we sometimes get four
sphinx-buildprocesses using up to 100% CPU each. This is good, we're making good use of the resources available. (Sometimes there's only 1-2 processes, depending on what part of the build Sphinx is at.)But most of the time it's running a latex command. These only use CPU, but at least generally use 100%:
Here's the time between the "Build start"/"Build done" pairs:
table of build times
We're spending a LOT of time churning out those PDFs: an hour or two per language/version.
Stepping back a moment, the cron entry is:
This script builds all languages and versions, and currently takes about 30 hours for a full batch.
The cron triggers at 7 minutes past the hour. If there's a build currently running, the new one just ends.
Suggestion: split HTML and PDF builds
I suggest we have two cron jobs. One that builds only HTML, the other that does everything else except HTML.
We'd allow these to run at the same time. A full HTML batch should be very quick. For example, the Ukrainian build is HTML only and takes 3 minutes. 13 languages x 3 minutes = 39 minutes.
We'd get docs HTML updates out the door quickly: ~30 minutes instead of ~30 hours! I also expect many of the next hourly triggers would not to need to rebuild anything, because there's less likely to be new docs changes after one hour compared to 30 hours.
I expect the other cron job that does non-HTML would still take about as long as now, as it's mostly churning out latex files on a single process. But we're more efficiently using the other CPUs for HTML.
I don't have download numbers for the PDFs etc, but I expect they're used much less than the HTML. And HTML is read live on the web right now, others are downloaded for reference and will (maybe) be re-downloaded at some later date.
In fact, I just spotted that #127 / python/psf-salt#236 said we used to build PDFs daily and the docs hourly. That PR was merged two years ago, shall we go back to this?
AA-Turner commentedon Aug 17, 2024
I would even suggest building PDFs every 36/48 hours. The main problem with building PDFs less often seems to have been new releases (especially .0) don't have PDF versions at release date, but this seems surmountable.
It seems that we could run multiple
latexmkprocesses for each build (ref: https://tex.stackexchange.com/a/699204) which might improve things -- I'll try and have a look if no one beats me to it.A
jfbu commentedon Aug 17, 2024
Sounds promising. I can not really test, but wouldn't
-joption ofmake(in the builddir) help here?I tried running directly latexmk as in https://tex.stackexchange.com/a/699204 but on my system it does not exit once job completes one has to hit RET; besides one should not run it directly so I tried adding the
&inside the Makefile rule, same issue, then I tried&withmake foo.pdf &,make foo2.pdf &again same issue, and finally-jappears to work:make -j all-pdfin the latex builddir.But here it should be I guess the with the largest
.texfiles first somake -j library.pdf c-api.pdf reference.pdf <here the others>(in the latex builddir or with-Coption) and not thismake -j all-pdfI tried.(I already admitted being on a single core system, so I can not vouch this will use multiple cores in real life).
As per my earlier comment about
-xelatexoption, see sphinx-doc/sphinx#12636. Best sure way to gain some time is to run the whole build in a TeXLive2019 environment not a TeXLive2024 one. Of course if that is compatible with extras from conf.py (fonts configuration?) which I have not checked here. Core Sphinx (even latest current version) produces exactly same result in a TL2019 based environment as in a TL2024 one.AA-Turner commentedon Aug 17, 2024
It turns out we have inadvertently been running the full
latexmkprocess twice for every build, since around 2010. Luckily, this is fixable.The LaTex build in Sphinx generates a makefile which we use to run latexmk and generate the actual PDFs from the
.texsources that Sphinx creates. In CPython'sDoc/Makefile, we call that makefile in a submake:(cd build/latex; make clean && make all-pdf && make FMT=pdf zip bz2).Considering the generated Makefile at
Doc/build/latex/Makefile, theall-pdftarget depends on$(ALLPDF), a list of every desired PDF file. Thezipandbz2targets also depend on$(ALLPDF). All three ofall-pdf,zip, andbz2are.PHONYtargets, which are evaluated every timemakeruns. Normally, this wouldn't present an issue, as thezipandbz2targets depend on$(ALLPDF)rather thanall-pdf, so make would know not to rebuild the PDF files. The issue becomes clear with the%.pdftarget. By depending on the.PHONYtargetFORCE_MAKE, PDF files are forcibly regenerated on both invocations ofmake, bypassing the inbuilt artefact caching.Resolving this is straightforwards, and I have a branch prepared to open a PR to CPython. EDIT: I have opened the PR at python/cpython#123113.
Sample timings (8 core CPU, via WSL):
-xelatexmake -j LATEXMKOPTS="-xelatex" all-pdf && make FMT=pdf zip bz2make -j LATEXMKOPTS="-xelatex" all-pdf && make FMT=pdf zip bz2-xelatexmake -j all-pdf && make FMT=pdf zip bz2make -j12 all-pdf && make FMT=pdf zip bz2I am proposing to use the final option, as whilst not the absolute fastest, it helps to mitigate scheduling problems, and the docs server only has 4 CPU cores, per Hugo's comment. It seems that
-xelatexdoesn't make a massive difference here.A
jfbu commentedon Aug 17, 2024
Good catch! The blame is on me at sphinx-doc/sphinx@409605d, but to my defence former Makefile did 5 (pdf)latex builds each time. Actually re-reading your post I am wondering if
latexmkreally triggers againxelatex. It should say something like this (this is an example on a dummy project)jfbu commentedon Aug 17, 2024
I think one has to make sure none of the 4 or 5 biggest files end up being handled by same core which may require a more complex layer to first list files as per decreasing filesizes of the
.texand feed them in that order tomakeas pdf targets.Yes Sphinx docs is too optimistic about this. It makes a difference when build documents does a ton of graphics inclusions.Sphinx docs does say it makes a difference in case of tons of graphics inclusions.hugovk commentedon Aug 25, 2024
With @AA-Turner's latexmk improvements (#169 (comment)) we're saving about a third of the time!
Here's a difference in the build times (not publish and so on) for a full set of 3.14 builds:
PS Here's the separate before and after times, and the script I used to get the times from the server build times.
before
after
calc-times.py
jfbu commentedon Aug 25, 2024
If you can build in an environment with a LaTeX distribution based upon TeXLive 2019 you will probably observe 30% or more additional gain. See this comment. I can not guarantee it completely because the comment compared builds on TL2019 and TL2024 and you use a Debian TL2023, so the gain might not be as much (I currently can not test on a TL2023). The PDFs will be exactly identical.
edit: I mean will look and print identical. Perhaps things are different regarding copy-paste from PDF and some other matters.
(I can not quantify at this time if the change from TL2023 to TL2024 induced the major part in slow-down of LaTeX kernel, or if it occurred earlier).
hugovk commentedon Aug 25, 2024
Another 30% or more would be very welcome! But I'm not too sure if we should downgrade to an unsupported version? (Or how to do it.)
jfbu commentedon Aug 25, 2024
A docker image is available for all TeXLive versions since 2014. The problem is that it contains the full thing which is much much more than what is strictly needed for Sphinx
make latexpdfeven leaving aside all sources and all documentation. Unfortunately I have personally no experience with this (having multiple TeXLive's on my computer already there), and to start with I have no idea if you can use such a Docker image and if its large size is an impediment (and I have other tasks now).There is a sphinx-latexpdf Docker image used for our CI, if I knew the recipe I could modify it to use TeXLive2019. And in the process try to use a much smaller part of full TeXLive hence construct a much smaller Docker image. But this is time-consuming task for which I don't have the immediate qualifications.
hugovk commentedon Sep 18, 2024
Update, we've cut the build times by around another third, by cutting about 15h per full build loop through dropping the letter PDF build (and keeping A4 PDF):
And by about an extra half an hour by re-using an HTTPS connection for purging CDN URLs:
AA-Turner commentedon Sep 23, 2024
It seems we're currently running around 10h 40m for each version -- Python 3.13 hasn't done a full rebuild in a while as the last commit was a fortnight ago (save around a dozen in the last half-hour!). This would be roughly 32 hours for a full rebuild of 3.12--3.14.
Timings:
(reason is 'translation' if an updated translation caused the rebuild rather than updated docs, and 'FULL BUILD' captures the end of a full rebuild loop. The loops that are 'empty' but around 30m long attempt a build of
fr/3.13and fail, see #187)A
hugovk commentedon Sep 23, 2024
This initially caught me by surprise but is expected; the 3.13 branch is locked for RC2, so there's not been much merged on the branch recently:
merwok commentedon Oct 1, 2024
This is the recipe: https://github.com/csotomon/sphinx-docker/blob/master/latexpdf/Dockerfile
AA-Turner commentedon Oct 1, 2024
That link is to a fork, though it's unclear -- the up-to-date dockerfile is at https://github.com/sphinx-doc/sphinx-docker-images/blob/master/latexpdf/Dockerfile
AA-Turner commentedon Oct 2, 2024
I suggest that we close this issue in favour of #209, now that python/docs-community#131 has been implemented. The non-HTML archive builds still take a while, but it's a manageable duration and we now have the luxury of adjusting the frequency of those builds to e.g. once every two days rather than daily.
Thank you to everyone involved for the help in reducing build times, we have made significant strides here in a challenging problem straddling multiple teams, projects, and repos.
A
hugovk commentedon Oct 2, 2024
Here's a summary of the current times, much improved:
python/docs-community#131 (comment)
Yes, let's close and continue in other issues as needed.
Thanks all!