[ANN] Turing 0.9.0

Turing 0.9 has been released. Bugs have been fixed and we’ve got new features and some key performance improvements.

Precompilation and using Turing time should be dramatically improved. Informal benchmarks suggest that precompilation time has improved from 97 seconds in 0.8.3 to 33 seconds in 0.9.0. Much all of this improvement came from changes in MCMCChains, which has recently had a lot of bloat removed. Hats off to @devmotion for good engineering and generally keeping me from building unstable, untested, and low-quality code.

@torfjelde did a bit of an overhaul on Turing’s variational inference engine. You can now use DecayedADAGrad as your optimizer, get a mean-field approximation of your model with meanfield(model), and you’ll benefit from the tighter integration with Bijectors. You should check out the whole PR if you like VI, there’s a lot more there.

Turing’s Metropolis-Hastings sampler MH() now uses AdvancedMH.jl on the backend, instead of the legacy hard-coded MH sampler. Users should now have much higher sampling speeds when using MH(). AdvancedMH is still an early project, so please open any issues if you find bugs when using Metropolis-Hastings sampling.

Thanks folks!

21 Likes

Thank you!

I tried to install it on a Windows 10 machine with a fresh Julia 1.31 installation and was not able to precompile Turing, it could not build Libtask:

LoadError: could not open file C:\Users\Aschi.julia\packages\Libtask\RjRkK\deps\deps.jl

I checked on

https://github.com/TuringLang/Libtask.jl/tree/master/deps

and did not find a deps.jl file here either.

Edit: Seems like it installs version v0.8.3 per default.

Try running ] add Turing@0.9.0. This should force Pkg to tell you what package is preventing you from updating to 0.9. You can remove that package, add Turing, and then add your package back.

This is great news – thank you for the improvements!

Would you mind sharing any insights or advice from this effort on the type of “bloat” that made the biggest difference in precompile time in Turing and MCMCChains? Often, my packages tend to have a precompile time that grows quite a bit as I add features. It’s a tough performance issue to profile and improve.

1 Like

Sure. I think there were a couple things that helped here.

  1. We used “heavy” packages in MCMCChains, such as DataFrames. DataFrames were used to report parameter statistics and to do some intermediate numerical calculations, but they have a really high spin up time at a place when it was not helpful. Since they were mostly being used for display purposes, we removed the DataFrames backend and just wrote our own print/display functionality. You can still use some DataFrames functionality, but it’s lazily loaded with Requires.
  2. One of the fixes was a weird one, which I think was mostly due to type inference problems. You can see the discussion here, but the fix amounted to basically re-configuring how MCMCChains handled chain concatenation.
  3. I had extended some functions from Base in a way that caused a bunch of precompilation difficulties. One line in particular caused the MCMCChains load time to decrease from ~20 seconds to ~6 seconds was to change
Base.convert(::Type{T}, cs::Array{ChainDataFrame,1}) where T<:Array

to

Base.convert(::Type{Array}, cs::Array{C,1}) where C<:ChainDataFrame

This one was very hard to find – I just commented out files one at a time until I saw big performance improvements, and then I started commenting out specific functions in files that caused big performance drops. Impractical for very large projects, but I think MCMCChains is small enough that I can do this sort of thing.

@devmotion do you have any other comments that might be helpful?

7 Likes

I think @cpfiffer mentioned the most important points. Just to explain the second point a bit more, the main issue in the previous implementation of cat was that the implementation invalidated the default implementation in Base since it was implemented as cat(chains::Chains...) which invalidates the default implementation of cat() (corresponding PR). Otherwise, we removed a bunch of type instabilities, unused imports, and occurrences of Int64.

4 Likes

Thank you both for the tips! I will see if some of these improvements can be applied to my packages.