TuringLang/Turing.jl
Bayesian inference with probabilistic programming.
📦 Turing v0.45.0
- [Diff since v0.44.5](https://github.com/TuringLang/Turing.jl/compare/v0.44.5...v0.45.0)
💥 Breaking changes
- Make FlexiChains the default chain type for MCMC sampling.
- MCMCChains is still fully supported: you can specify `chain_type=MCMCChains.Chains` in the `sample` function to use it instead.
- However, it is no longer loaded as a dependency of Turing and re-exported (it is now an extension).
- That means that if you were previously importing MCMCChains via Turing, you will now have to import it directly.
- Merged pull requests:
- Make FlexiChains the default chain type (#2743) (@penelopeysm)
- add Claude stuff (#2822) (@penelopeysm)
- Closed issues:
- + 1 more
📦 Turing v0.44.5
- [Diff since v0.44.4](https://github.com/TuringLang/Turing.jl/compare/v0.44.4...v0.44.5)
- Allow users to disable the post-sample hook by passing `verbose=false` keyword argument to `sample`.
- Merged pull requests:
- Allow post sample hook to be controlled by kwargs (#2821) (@penelopeysm)
📦 Turing v0.44.4
- [Diff since v0.44.3](https://github.com/TuringLang/Turing.jl/compare/v0.44.3...v0.44.4)
- Add post-sampling warning message when there are divergent transitions with `HMC`, `NUTS` or `HMCDA`.
- Merged pull requests:
- Fix NUTS docstring formatting to match HMC and HMCDA style (#2818) (@ArpanC6)
- adding info_sampler_output method to track divergences (#2819) (@PavanChaggar)
📦 Turing v0.44.3
- [Diff since v0.44.2](https://github.com/TuringLang/Turing.jl/compare/v0.44.2...v0.44.3)
- Add compatibility with SciMLBase v3.
- Merged pull requests:
- CompatHelper: bump compat for SciMLBase to 3, (keep existing compat) (#2802) (@github-actions[bot])
- Add contribution policy (#2815) (@yebai)
- Update README.md (#2816) (@yebai)
- Update README.md (#2817) (@yebai)
📦 Turing v0.44.2
- [Diff since v0.44.1](https://github.com/TuringLang/Turing.jl/compare/v0.44.1...v0.44.2)
- Fix a bug in v0.44 where extra keyword arguments passed to `vi` (e.g. `callback`) would cause Turing to error.
- Merged pull requests:
- Fix failing kwargs in VI (#2813) (@penelopeysm)
📦 Turing v0.44.1
- [Diff since v0.44.0](https://github.com/TuringLang/Turing.jl/compare/v0.44.0...v0.44.1)
- Re-export `pointwise_logdensities` and `pointwise_prior_logdensities` from DynamicPPL.
- Merged pull requests:
- Reexport other pointwise density functions (#2812) (@penelopeysm)
📦 Turing v0.44.0
- [Diff since v0.43.7](https://github.com/TuringLang/Turing.jl/compare/v0.43.7...v0.44.0)
💥 Breaking changes
- Variational inference interface
- The VI interface in Turing has been modified to make it more interoperable with the rest of Turing.
- The arguments to `vi(...)` are slightly different: instead of specifying a `q_init` argument (the initial variational approximation), you now directly pass a function that constructs this for you. For example, instead of
- ```julia
- q_init = q_meanfield_gaussian(model)
- vi(model, q_init, n_iters)
- ```
- you would now do
- + 24 more
📋 Other changes
- Performance
- Previously many of Turing's samplers needed to carry around a VarInfo so that they could communicate with Gibbs.
- This release frees them up from having to do so, and in particular allows for usage of `DynamicPPL.OnlyAccsVarInfo`, which is much cheaper as it avoids unnecessary computations.
- As a result, samplers such as MH and ESS are faster in this release, sometimes by up to 5x.
- Fixed transforms
- (In contrast, the default behaviour is to rederive transforms each time the model is run.)
- Note that not all MCMC samplers currently support fixed transforms.
- For some samplers such as ESS and particle MCMC, fixed transforms do not affect the sampling process at all (in such cases the keyword argument is accepted but ignored).
- + 18 more
📦 Turing v0.43.7
- [Diff since v0.43.6](https://github.com/TuringLang/Turing.jl/compare/v0.43.6...v0.43.7)
- Fixes an issue where sampling with `MH()` in v0.43 would not include `x := expr` results in the chain.
- Merged pull requests:
- DynamicPPL@0.41 (#2800) (@penelopeysm)
- Fix := statements with MH (#2809) (@penelopeysm)
📦 Turing v0.43.6
- [Diff since v0.43.5](https://github.com/TuringLang/Turing.jl/compare/v0.43.5...v0.43.6)
- Internal change to avoid using ForwardDiff internals.
- Merged pull requests:
- Remove `ForwardDiff.value` (#2805) (@penelopeysm)
- Closed issues:
- Gibbs soapbox (#2540)
📦 Turing v0.43.5
- [Diff since v0.43.4](https://github.com/TuringLang/Turing.jl/compare/v0.43.4...v0.43.5)
- Fix incorrect handling of VarNamedTuple templates inside submodels when sampling with Gibbs.
- Merged pull requests:
- Fix Gibbs/submodel/template handling bug (#2799) (@penelopeysm)
- Closed issues:
- Gibbs / submodel bug (#2797)
- Broken interaction between Gibbs Sampler and Submodels with Vector assignment (#2798)
📦 Turing v0.43.4
- [Diff since v0.43.3](https://github.com/TuringLang/Turing.jl/compare/v0.43.3...v0.43.4)
- Fix some missing `Base.copy` implementations on internal structs.
- Merged pull requests:
- Fix some missing `Base.copy` implementations (#2796) (@penelopeysm)
- Closed issues:
- Integrate SSMProblems & GeneralisedFilters with Turing.jl (#2428)
- SMC sampling incorrectly (#2656)
📦 Turing v0.43.3
- [Diff since v0.43.2](https://github.com/TuringLang/Turing.jl/compare/v0.43.2...v0.43.3)
- Unify parameter initialisation for HMC and external samplers.
- External samplers (like HMC) now attempt multiple times to generate valid initial parameters, instead of just taking the first set of parameters.
- Re-exports `set_logprob_type!` from DynamicPPL to allow users to control the base log-probability type used when evaluating Turing models.
- Note that this is a compile-time preference: for it to take effect you will have to restart your Julia session after calling `set_logprob_type!`.
- Furthermore, note that sampler support for non-`Float64` log-probabilities is currently limited.
- Merged pull requests:
- Unify HMC + externalsampler + DynamicHMC parameter initialisation; re-export `DynamicPPL.set_logprob_type!` (#2794) (@penelopeysm)
- + 17 more
📦 Turing v0.43.2
- [Diff since v0.43.1](https://github.com/TuringLang/Turing.jl/compare/v0.43.1...v0.43.2)
- Throw an `ArgumentError` when a `Gibbs` sampler is missing component samplers for any variable in the model.
- This check can be bypassed by passing `check_model=false` to `sample`.
- Merged pull requests:
- Throw an error when Gibbs sampler is missing components for any variable (#2788) (@hardik-xi11)
- Closed issues:
- Should the initial parameter samples / values be recorded for each chain (#1282)
- MH currently does not support link/invlink properly on a per-variable basis (#1583)
- + 4 more
📦 Turing v0.43.1
- [Diff since v0.43.0](https://github.com/TuringLang/Turing.jl/compare/v0.43.0...v0.43.1)
- Ignore `discard_initial` and `thinning` for `SMC` samplers to prevent a `BoundsError` when these arguments are provided.
- Merged pull requests:
- Ignore discard_initial and thinning for SMC (#2784) (@hardik-xi11)
- Closed issues:
- SMC throws BoundsError when discard_initial > 1 or thinning > 1 (#1811)
📦 Turing v0.43.0
- [Diff since v0.42.9](https://github.com/TuringLang/Turing.jl/compare/v0.42.9...v0.43.0)
📦 DynamicPPL 0.40 and `VarNamedTuple`
- DynamicPPL v0.40 includes a major overhaul of Turing's internal data structures.
- Most notably, cases where we might once have used `Dict{VarName}` or `NamedTuple` have all been replaced with a single data structure, called `VarNamedTuple`.
- This provides substantial benefits in terms of robustness and performance.
- However, it does place some constraints on Turing models, and introduces some breaking changes to the user interface.
- Specifically, the types of containers that can include random variables are now more limited:
- if `x[i] ~ dist` is a random variable, then `x` must obey the following criteria:
- They must be `AbstractArray`s. Dicts and other containers are currently unsupported (we have [an issue to track this](https://github.com/TuringLang/DynamicPPL.jl/issues/1263)). If you really need this functionality, please open an issue and let us know; we can try to make it a priority.
- ```julia
- + 26 more
🐛 Conditioning and fixing
- When providing conditioned or fixed variables to Turing models, we recommend that you use a `VarNamedTuple` to do so.
- The main benefit of this is that it correctly captures the structure of arrays of random variables.
- There were also similar inconsistencies with colons in variable names.
- With a VarNamedTuple-based approach, both should be equivalent: you can do
- ```julia
- vnt1 = @vnt begin
- @template x = zeros(2)
- x[1] := 1.0
- + 9 more
📦 Optimisation interface
- Turing.jl's optimisation interface has been completely overhauled in this release.
- The aim of this has been to provide users with a more consistent and principled way of specifying constraints.
- The crux of the issue is that Optimization.jl expects vectorised inputs, whereas Turing models are more high-level: they have named variables which may be scalars, vectors, or in general anything.
- If specific parameters are provided (via `InitFromParams`), these must be in model space (i.e. untransformed).
- This directly mimics the interface for MCMC sampling that has been in place since v0.41.
- Furthermore, lower and upper bounds (if desired) can be specified as `VarNamedTuple`s using the `lb` and `ub` keyword arguments.
- Bounds are always provided in model space; Turing will handle the transformation of these bounds to linked space if necessary.
- Here is a (very simplified) example of the new interface:
- + 16 more
📋 Other changes to the optimisation interface
- `estimate_mode`, `maximum_a_posteriori`, and `maximum_likelihood` now accept an optional `rng` first argument for reproducible initialisation.
- New keyword argument `link::Bool=true` controls whether to optimise in linked (transformed) space.
- New keyword argument `check_constraints_at_runtime::Bool=true` enables runtime constraint checking during model evaluation.
- Generic (non-box) constraints via `cons`, `lcons`, `ucons` are no longer supported. Users who need these should use `LogDensityFunction` and Optimization.jl directly.
📋 `ModeResult` changes
- The return type from an optimisation procedure, `ModeResult`, has been substantially reworked:
- `ModeResult.params` is now a `VarNamedTuple` (previously an `AbstractDict{<:VarName}`). Parameters can be accessed via e.g. `m.params[@varname(x)]`.
- The `values::NamedArray` field has been removed. Use `vector_names_and_params(m)` (newly exported) to obtain `(Vector{VarName}, Vector{values})`.
- `Base.get(m::ModeResult, ...)` has been removed; use `m.params[@varname(x)]` instead.
- `StatsBase.coef` now returns a plain `Vector` (not a `NamedArray`).
- `StatsBase.coefnames` now returns a `Vector{VarName}` (not strings or symbols).
- `StatsBase.informationmatrix`: the `hessian_function` keyword argument has been replaced by `adtype::ADTypes.AbstractADType` (default `AutoForwardDiff()`). Hessian computation uses DifferentiationInterface under the hood.
📦 `IS` sampler
- The `IS` sampler has been removed (its behaviour was in fact exactly the same as `Prior`).
- To see an example of importance sampling (via `Prior()` and then subsequent reweighting), see e.g. [this issue](https://github.com/TuringLang/Turing.jl/issues/2767).
📦 `MH` sampler
- The interface of the MH sampler is slightly different.
- It is also faster than before (by around 30% on simple models).
- Additional changes:
- A new type `LinkedRW` allows specifying random-walk proposals in linked (unconstrained) space, e.g. `MH(@varname(x) => LinkedRW(cov_matrix))`.
- Callable (conditional) proposals now receive a `VarNamedTuple` of the full parameter state, rather than a single scalar. For example:
- ```julia
- MH(:m => x -> Normal(x, 1))
- MH(@varname(m) => (vnt -> Normal(vnt[@varname(m)], 1)))
- + 4 more
📦 Gibbs sampler
- Both the compilation and runtime of Gibbs sampling should now be significantly faster.
- (This is largely due to the underlying changes in DynamicPPL's data structures.)
📦 HMC / NUTS
- HMC-family samplers now check for discrete variables before sampling begins.
- If a model contains discrete variables (e.g. `x ~ Categorical(...)`) and an HMC sampler is used, an `ArgumentError` is thrown immediately.
- Previously, this would silently proceed.
📦 `GibbsConditional`
- When defining a conditional posterior, instead of being provided with a Dict of values, the function must now take a `VarNamedTuple` containing the values.
📦 `filldist` and `arraydist`
- These two convenience functions are now imported and re-exported from DynamicPPL, rather than DistributionsAD.jl.
- They are now just wrappers around `Distributions.product_distribution`, instead of the specialised implementations that were in DistributionsAD.jl.
- DistributionsAD.jl is for all intents and purposes deprecated: it is no longer a dependency in the Turing stack.
- Merged pull requests:
- breaking - v0.43 (#2733) (@penelopeysm)
- Remove Random.seed! from test suite, use Xoshiro/StableRNG instead (#2779) (@anurag-mds)
- Closed issues:
- Gibbs Compilation Performance (#2542)
- + 2 more
📦 Turing v0.42.9
- [Diff since v0.42.8](https://github.com/TuringLang/Turing.jl/compare/v0.42.8...v0.42.9)
- Improve handling of model evaluator functions with Libtask.
- This means that when running SMC or PG on a model with keyword arguments, you no longer need to use @might_produce (see patch notes of v0.42.5 for more details on this).
- Merged pull requests:
- Run CI against new DPPL / VNT (#2756) (@penelopeysm)
- CompatHelper: bump compat for Mooncake to 0.5 for package test, (keep existing compat) (#2758) (@github-actions[bot])
- Tell users about the proposals that are being used in MH (#2774) (@penelopeysm)
- Mark all methods with `DynamicPPL.Model` as produceable (#2780) (@penelopeysm)
- + 4 more
📦 Turing v0.42.8
- [Diff since v0.42.7](https://github.com/TuringLang/Turing.jl/compare/v0.42.7...v0.42.8)
📦 Turing v0.42.7
- [Diff since v0.42.6](https://github.com/TuringLang/Turing.jl/compare/v0.42.6...v0.42.7)
- Avoid reevaluating the model on MCMC iterations where the transition is not saved to the chain (e.g. in initial burn-in, or when using thinning).
- Also avoid each component sampler of Gibbs unnecessarily evaluating the model once per iteration.
- Merged pull requests:
- Avoid reevaluating model where unnecessary (#2759) (@penelopeysm)
- Closed issues:
- Gibbs wastefully re-evaluates model once per component sampler per iteration (#2639)
📦 Turing v0.42.6
- [Diff since v0.42.5](https://github.com/TuringLang/Turing.jl/compare/v0.42.5...v0.42.6)
- Fixed a bug in SMC and PG where results were not always stored correctly in Libtask traces (due to incorrect `objectid` checks).
📦 Turing v0.42.5
- [Diff since v0.42.4](https://github.com/TuringLang/Turing.jl/compare/v0.42.4...v0.42.5)
- SMC and PG can now be used for models with keyword arguments, albeit with one requirement: the user must mark the model function as being able to produce.
- For example, if the model is
- ```julia
- @model foo(x; y) = a ~ Normal(x, y)
- ```
- then before sampling from this with SMC or PG, you will have to run
- ```julia
- + 12 more
📦 Turing v0.42.4
- [Diff since v0.42.3](https://github.com/TuringLang/Turing.jl/compare/v0.42.3...v0.42.4)
- Fixes a typo that caused NUTS to perform one less adaptation step than in versions prior to 0.41.
- Merged pull requests:
- Fix off-by-one NUTS adaptations (#2751) (@penelopeysm)
- Closed issues:
- HMC and NUTS treating prior as optional (#2749)
- state should be 0 not 1 (#2750)
📦 Turing v0.42.3
- [Diff since v0.42.2](https://github.com/TuringLang/Turing.jl/compare/v0.42.2...v0.42.3)
- Removes some dead code.
- Merged pull requests:
- Allow MLE test to fail (#2746) (@penelopeysm)
- remove get_matching_type overload (#2748) (@penelopeysm)
- Closed issues:
- Remove OptimizationOptimJL dep? (#2712)
- optimisation CI failures (#2744)
📦 Turing v0.42.2
- [Diff since v0.42.1](https://github.com/TuringLang/Turing.jl/compare/v0.42.1...v0.42.2)
- This also means that you can now invoke `returned(model, mode_estimate)` to calculate a model's return values given the parameters in `mode_estimate`.
- Merged pull requests:
- Test against Enzyme (#2636) (@wsmoses)
- Fix missing `fallback` argument for `InitFromParams(::ModeResult)` (#2736) (@penelopeysm)
- Closed issues:
- create `returned()` method for results from mode estimation (#2607)
📦 Turing v0.42.1
- [Diff since v0.42.0](https://github.com/TuringLang/Turing.jl/compare/v0.42.0...v0.42.1)
- Avoid passing a full VarInfo to `check_model`, which allows more models to be checked safely for validity.
- Merged pull requests:
- Use OnlyAccsVarInfo in check_model (#2742) (@penelopeysm)
- Closed issues:
- write better code for specification of initial params for optimisation (#2709)
- BoundsError in VI (#2731)
📦 Turing v0.6.15
- [Diff since v0.6.14](https://github.com/TuringLang/Turing.jl/compare/v0.6.14...v0.6.15)
- This release has been identified as a backport.
- Automated changelogs for backports tend to be wildly incorrect.
- Therefore, the list of issues and pull requests is hidden.
- <!--
- Merged pull requests:
- Test refactoring (#731) (@cpfiffer)
- TS 1: reorganize VarName and VarInfo and rename it to UntypedVarInfo (#740) (@mohdibntarek)
- + 7 more
📦 Turing v0.42.0
- [Diff since v0.41.4](https://github.com/TuringLang/Turing.jl/compare/v0.41.4...v0.42.0)
📦 DynamicPPL 0.39
- Turing.jl v0.42 brings with it all the underlying changes in DynamicPPL 0.39.
📦 Thread safety opt-in
- Turing.jl has supported threaded tilde-statements for a while now, as long as said tilde-statements are observations (i.e., likelihood terms).
- For example:
- ```julia
- @model function f(y)
- x ~ Normal()
- Threads.@threads for i in eachindex(y)
- y[i] ~ Normal(x)
- end
- + 17 more
⚡ Faster performance
- Many operations in DynamicPPL have been substantially sped up.
- You should find that anything that uses LogDensityFunction (i.e., HMC/NUTS samplers, optimisation) is faster in this release.
- Prior sampling should also be much faster than before.
📦 `predict` improvements
- If you have a model that requires threadsafe evaluation (i.e., parallel observations), you can now use this with `predict`.
- Carrying on from the previous example, you can do:
- ```julia
- model = setthreadsafe(f(y), true)
- chain = sample(model, NUTS(), 1000)
- pdn_model = f(fill(missing, length(y)))
- pdn_model = setthreadsafe(pdn_model, true) # set threadsafe
- predictions = predict(pdn_model, chain) # generate new predictions in parallel
- + 1 more
📦 Log-density names in chains
- Previously, `:logjoint` would be stored under the name `:lp`.
📦 Log-evidence in chains
- When sampling using MCMCChains, the chain object will no longer have its `chain.logevidence` field set.
- Instead, you can calculate this yourself from the log-likelihoods stored in the chain.
- For SMC samplers, the log-evidence of the entire trajectory is stored in `chain[:logevidence]` (which is the same for every particle in the 'chain').
📦 `Turing.Inference.Transition`
- `Turing.Inference.Transition(model, vi[, stats])` has been removed; you can directly replace this with `DynamicPPL.ParamsWithStats(vi, model[, stats])`.
📦 AdvancedVI 0.6
- Turing.jl v0.42 updates `AdvancedVI.jl` compatibility to 0.6 (we skipped the breaking 0.5 update as it does not introduce new features).
- `AdvancedVI.jl@0.6` introduces major structural changes including breaking changes to the interface and multiple new features.
- The summary of the changes below are the things that affect the end-users of Turing.
- For a more comprehensive list of changes, please refer to the [changelogs](https://github.com/TuringLang/AdvancedVI.jl/blob/main/HISTORY.md) in `AdvancedVI`.
💥 Breaking changes
- For example,
- ```julia
- q, q_avg, info, state = vi(
- model, q, n_iters; objective=RepGradELBO(10), operator=AdvancedVI.ClipScale()
- )
- ```
- is now
- ```julia
- + 41 more
✨ New Features
- `AdvancedVI@0.6` adds numerous new features including the following new VI algorithms:
- `KLMinWassFwdBwd`: Also known as "Wasserstein variational inference," this algorithm minimizes the KL divergence under the Wasserstein-2 metric.
- `KLMinNaturalGradDescent`: This algorithm, also known as "online variational Newton," is the canonical "black-box" natural gradient variational inference algorithm, which minimizes the KL divergence via mirror descent under the KL divergence as the Bregman divergence.
- `KLMinSqrtNaturalGradDescent`: This is a recent variant of `KLMinNaturalGradDescent` that operates in the Cholesky-factor parameterization of Gaussians instead of precision matrices.
- `FisherMinBatchMatch`: This algorithm called "batch-and-match," minimizes the variation of the 2nd order Fisher divergence via a proximal point-type algorithm.
- Any of the new algorithms above can readily be used by simply swappin the `algorithm` keyword argument of `vi`.
- For example, to use batch-and-match:
- ```julia
- + 2 more
📦 External sampler interface
- The interface for defining an external sampler has been reworked.
- In general, implementations of external samplers should now no longer need to depend on Turing.
- This is because the interface functions required have been shifted upstream to AbstractMCMC.jl.
- In particular, you now only need to define the following functions:
- `AbstractMCMC.step(rng::Random.AbstractRNG, model::AbstractMCMC.LogDensityModel, ::MySampler; kwargs...)` (and also a method with `state`, and the corresponding `step_warmup` methods if needed)
- `AbstractMCMC.getparams(::MySamplerState)` -> Vector{<:Real}
- `AbstractMCMC.getstats(::MySamplerState)` -> NamedTuple
- `AbstractMCMC.requires_unconstrained_space(::MySampler)` -> Bool (default `true`)
- + 3 more
📦 Optimisation interface
- The Optim.jl interface has been removed (so you cannot call `Optim.optimize` directly on Turing models).
📋 Internal changes
- The constructors of `OptimLogDensity` have been replaced with a single constructor, `OptimLogDensity(::DynamicPPL.LogDensityFunction)`.
- Merged pull requests:
- Update variational inference interface to match `AdvancedVI@0.6` (#2699) (@Red-Portal)
- [breaking] v0.42 (#2702) (@mhauru)
- Remove Optim.jl interface + minor tidying up of src/optimisation/Optimisation (#2708) (@penelopeysm)
- Update for DynamicPPL 0.39 (#2715) (@penelopeysm)
- Enable Mooncake on 1.12 (#2724) (@penelopeysm)
- CompatHelper: add new compat entry for Mooncake at version 0.4 for package test, (keep existing compat) (#2725) (@github-actions[bot])
- + 4 more
📦 Turing v0.41.4
- [Diff since v0.41.3](https://github.com/TuringLang/Turing.jl/compare/v0.41.3...v0.41.4)
- Fixed a bug where the `check_model=false` keyword argument would not be respected when sampling with multiple threads or cores.
- Merged pull requests:
- make MCMCThreads etc. respect `check_model=false` (#2721) (@penelopeysm)
📦 Turing v0.41.3
- [Diff since v0.41.2](https://github.com/TuringLang/Turing.jl/compare/v0.41.2...v0.41.3)
- Fixed NUTS not correctly specifying the number of adaptation steps when calling `AdvancedHMC.initialize!` (this bug led to mass matrix adaptation not actually happening).
- Merged pull requests:
- Fix incorrect nadapts being passed to AdvancedHMC (#2718) (@penelopeysm)
- Closed issues:
- Turing and AdvancedHMC give different adaptors for NUTS (#2717)
📦 Turing v0.41.2
- [Diff since v0.41.1](https://github.com/TuringLang/Turing.jl/compare/v0.41.1...v0.41.2)
- Add `GibbsConditional`, a "sampler" that can be used to provide analytically known conditional posteriors in a Gibbs sampler.
- Merged pull requests:
- Add dark/light mode logo support (#2714) (@shravanngoswamii)
- Closed issues:
- Reenable CI tests on Julia v1 (#2686)
- Error on running `using Turing` on latest version (#2711)
📦 Turing v0.41.1
- [Diff since v0.41.0](https://github.com/TuringLang/Turing.jl/compare/v0.41.0...v0.41.1)
- The `ModeResult` struct returned by `maximum_a_posteriori` and `maximum_likelihood` can now be wrapped in `InitFromParams()`.
- This makes it easier to use the parameters in downstream code, e.g. when specifying initial parameters for MCMC sampling.
- For example:
- ```julia
- @model function f()
- end
- model = f()
- + 15 more
