And a change of mind about the backend
London School of Hygiene & Tropical Medicine
14 August 2026
EpiNow2 configuration in three hourssamabbott.co.uk/JuliaCon2026/composable
JuliaCon 2026, Muschel — N3, Friday 14 August 2026, 16:45.
Whitty (2015), doi:10.1186/s12916-015-0544-8
Birrell et al. (2025), doi:10.1093/jrsssa/qnaf030
Endo et al. (2022), doi:10.1126/science.add4507
Hay et al. (2021), doi:10.1126/science.abh0635
The US COVID-19 Forecast Hub dataset. Cramer et al. (2022), doi:10.1038/s41597-022-01517-w
Prevalence (A), incidence (B), antibody prevalence (C) and \(R_t\) (D) fitted together as one model instead. Abbott and Funk (2022), doi:10.1101/2022.03.29.22273101. Survey figures from the paper’s introduction
Lison et al. (2024), doi:10.1371/journal.pcbi.1012021
primarycensored is one, and uptake outside my own packages is thinThe two sharing a component are EpiNow2 and epinowcast, both vendoring primarycensored.stan · epiforecasts.io/EpiNow2
What is composable modelling?
Components can be reused across contexts and combined in different configurations whilst maintaining statistical rigour.
Warning
These were developed by the authors and have not yet received broader community input.
Table 1 of the paper pairs each requirement with the problem that motivates it, under six themes. Three of the twelve are on the left. All twelve are at epiaware.org/approaches
ComposableTuringIDModels.jlRegistered in General at v0.1.1, so ] add ComposableTuringIDModels works · github.com/EpiAware/ComposableTuringIDModels.jl · Abbott et al., Composable probabilistic models can lower barriers to rigorous infectious disease modelling, in CDC clearance
Four illustrative applications, not implementations. The incubation period model appears in all four and the latent infection model in three
using ComposableTuringIDModels, Distributions, Turing, Accessors
ar2 = AR(;
damp = [truncated(Normal(0.2, 0.2), 0, 1),
truncated(Normal(0.1, 0.05), 0, 1)],
ϵ_t = HierarchicalNormal(std = HalfNormal(0.1)))
ma1 = MA(;
θ = [truncated(Normal(0.0, 0.2), -1, 1)],
ϵ_t = HierarchicalNormal(std = HalfNormal(0.1)))
arma21 = @set ar2.ϵ_t = ma1
arima211 = DiffLatentModel(arma21, Normal(0, 0.2); d = 1)
mdl = IDModel(
DirectInfections(; Z = arima211, initialisation = Normal()),
PoissonError())
chain = sample(as_turing_model(mdl, cases, n), NUTS(), 1_000)@set is Accessors.jl, not ours, and works because the components are plain immutable structs · Keywords track main. The paper’s artefact pins an earlier release, where these were damp_priors, θ_priors and std_prior
Note
AR was never told that MA exists.
EpiNow2 configurationbroadcast_weekly wraps the ARIMA for piecewise constant weekly \(R_t\), and ascertainment_dayofweek adds day-of-week reportingLatentDelay wrappers add the incubation period and the reporting delayImportant
No component was edited. The replication took three hours.
Figures 2 and 4 of the paper. Replicating a common configuration of EpiNow2, real-time estimation accounting for reporting delays, right truncation and day-of-week effects. Abbott et al. (2020), doi:10.12688/wellcomeopenres.16006.2. Daily COVID-19 cases from Italy, February to June 2020, shipped with EpiNow2. One configuration replicated, not a benchmark against the package
From the Turing.jl documentation
“not all AD libraries in there are thoroughly tested on Turing models. Thus, it is possible that some of them will either error … or maybe even silently give incorrect results”
Release dates from the GitHub API, 2026-08-10 · v0.35.5 is the release the paper’s artefact pins · turinglang.org/docs/usage/automatic-differentiation · The two practical limits are in the paper’s discussion · We run six autodiff configurations in CI instead, which was the 14:30 talk in this room, samabbott.co.uk/JuliaCon2026/roadmap
TuringLang/ADTests, the one public per-backend support table for a probabilistic programming stack, was archived in JuneEpiAwareADTools.jl is where we keep our autodiff workarounds. We delete them when upstream ships a fix| Commits, last six months | Turing.jl | DynamicPPL.jl |
|---|---|---|
| Human authors | 29 | 72 |
| One person | 17 | 47 |
Commit counts from the GitHub API, 2026-08-10, main, human authors only, so 17 of 29 and 47 of 72 are per repository · DynamicPPL.jl is where most of the composition machinery lives · TuringLang/ADTests, archived 2026-06-15
Distributions.jl distribution is already an interface the whole of Julia understands, so write the epidemiology as distributions and the probabilistic programming language becomes optionalCensoredDistributions.jl does not depend on Turing. Nothing in src/ mentions itConvolvedDistributions.jl through a package extension, and neither is a hard dependency of the otherCensoredDistributions.jl v0.2.22, main, checked 2026-08-11. ConvolvedDistributions is a [weakdeps] entry carrying the extension CensoredDistributionsConvolvedDistributionsExt, and neither package is in the other’s [deps] · The type is the output of scripts/composable-composed-type.jl, run for this talk, with the parameter types dropped, and cdf needed no telling about it
| Piece of a model | Is it a distribution? |
|---|---|
| Delay, censored and truncated | Yes, today |
| Renewal process | No |
| ARIMA latent process | No |
| ODE | No |
| The fitting layer | No |
Open issue CensoredDistributions.jl#749 says the joint fit is too slow, because reverse mode autodiff through cdf(Convolved(...)) costs too much per step · The delay side is written up in full at samabbott.co.uk/JuliaCon2026/delays
Important
I have argued myself into both answers.
The alternative approaches, including NumPyro and JAX, are in the paper’s discussion. The paper is in CDC clearance · The six autodiff configurations were the 14:30 talk in this room, samabbott.co.uk/JuliaCon2026/roadmap
Important
Tell me what you would build this on, if not a probabilistic programming language.
samabbott.co.uk/JuliaCon2026/composable
The prototype is ComposableTuringIDModels.jl, github.com/EpiAware/ComposableTuringIDModels.jl
Sam Abbott, LSHTM · epiaware.org · github.com/seabbs
Nobody outside the author team has built a model with this
Until somebody outside tries, the title is an argument rather than a result.
In the proof of concept
In the claim
Note
EpiAwareR, Sebastian Funk’s prototype R interface, ran two of the three replications. That is the closest thing to outside use so far.
Replicating Mishra et al. (2020). Figure from the paper
ODEProcess over the SciML solvers insteadAscertainment driven by an AR(1)Important
The infection process changed and nothing downstream had to.
Replicating Chatzilena et al. (2019), doi:10.1016/j.epidem.2019.100367. An influenza outbreak in an English boarding school, 1978. Figure 5 of the paper. The paper’s text reads \(R_0 \approx 2\) off this panel. Panel C looks closer to 4 to me, and I have not resolved which is right
| Approach | How it composes |
|---|---|
| AlgebraicJulia | Formal compositional guarantees, and little support for probabilistic models |
JuliaBUGS.jl, RxInfer.jl |
Models specified as graphs |
ModelingToolkit.jl |
Acausal components, symbolically |
Gen.jl |
Nested generative functions, at a lower level than Turing.jl |
The paper’s discussion of alternative designs
This claim is in the paper’s discussion. It has not been tested.
What is composable modelling?
Components can be reused across contexts and combined in different configurations whilst maintaining statistical rigour.
Whitty (2015), doi:10.1186/s12916-015-0544-8 · Birrell et al. (2025), doi:10.1093/jrsssa/qnaf030 · Endo et al. (2022), doi:10.1126/science.add4507 · Lison et al. (2024), doi:10.1371/journal.pcbi.1012021
Four illustrative applications, not implementations. The incubation period model appears in all four, the latent infection model in three, and the band beneath is what those shared components are themselves made of. Figure 1 of the paper, which is in CDC clearance. The design considerations behind it are at epiaware.org/approaches
EpiNow2 configuration, rebuilt out of partsbroadcast_weekly for weekly \(R_t\), day-of-week ascertainment around the observation model, and two LatentDelay wrappers for the incubation period and the reporting delayImportant
Nothing here required editing a component that already existed. The replication took three hours.
One of three replications in the paper, alongside a renewal model of South Korea and an ODE model of influenza. Replicating EpiNow2 (Abbott et al., 2020). Figures from the paper, which is in CDC clearance. The prototype is ComposableTuringIDModels.jl