Hi @daslu, @hoppy and I have made some headway into understanding what an ffi wrapper for STAN with bridgestan might look like. However, it unfortunately seems like the architecture of bridgestan means that there's not much benefit over cmdstan. More details in ๐งต
Here's the basic flow for a typical usage of bridge stan:
1. write a .stan file with a model description
2. Use the cli stanc tool to compile the model to a shared library
3. load the shared library via the JVM
4. construct the model and pass it data via a JSON filename or string
5. run the model
Typically, wrapping a native library has the benefits of improving performance and simplifying deployment. Passing data via a json string negates the benefits of shared memory and means performance is probably not much better. Requiring stanc from a local stan installation means that deploying models isn't much easier unless you can precompile the model ahead of time. If you need to tweak and recompile models, then you need to shell out to stanc regardless.
We were wondering whether there are any other benefits of a bridgestan approach for existing use cases.
Hi! That is great. Thanks for these notes. For using Stan "the usual way", indeed it may not add much. Bridgestan will mostly be helpful in writing our own inference algorithms, and can be a foundation for a Clojure library for Bayesian Statistics. I will write more a bit later.
so the use case of "I wanna bundle my prebaked stan model with some higher-level library is what we would be shooting at?" I see some point in that.
that's a perfect way to explain it!
I've done something similar before with Sqlite extension modules. The thing that makes this hard is that you are effectively proposing shipping a boatload of different platform specific libs and picking the right one at runtime. You would need your stan models compiled for quite a few platforms, and hope it all mates up on the target.
Ohh I see
stan-model -> stanc -> g++ -> dirty native .so
That is a good question. I will try to learn more about how they did it in other languages.
It looks like the intent is that you pull bridgestan and it pulls the pieces together for you to do the native build yourself with minimal ceremony. You just need a viable g++ toolchain, for your platform, available
I would do that, then run my python to snarf in the .so with an import.
the "bridge" part is effectively a loader with a "clean" interface that in turns loads the stanc generated gnarl
it goes circular - want to avoid native compilation, so we strap on a prebuilt library that has virutally no chance of working on the target unless it's built natively.
As we discussed, this is not high priority for our short-term needs. We thought it would be an easy use case for exploring interop, but it turns out more complicated. Maybe the next step should be to justify it with a use case, e.g. by first using the BridgeStan bindings of another language, and connecting to them from Clojure by some way of communication between two processes.
(To motivate our interest in it, there is a currently going discussion in the Zulip chat about a topic called Active Inference, where our program not only infers but also acts. Then, observations are interlaced with actions, in a changing environment. To explore such systems in Clojure, BridgeStan seems like the right level of abstraction we could hope for. But this is not a high priority as far as I understand.)
------------ So, if this seem troublesome on the implementation side, I would suggest puting it on hold till we demonstrate what we want (which may take some time). Does it make sense?
I would bring up CmdStan in this context, and ask what sort of use case breaks this or makes it ugly
we can certainly make the bridgestan c-shim into an FFI type deal, which would at least give you the benefit of not having to restart an executable on every call into the model.
you would still be left with having to have a native-built .so for your box in hand - it would just give you a way to manage lifecycle a little better.
> I would bring up CmdStan in this context, and ask what sort of use case breaks this or makes it ugly Exactly. I'm proposing we will explore some use cases (like active inference) where https://scicloj.github.io/cmdstan-clj/ are not good enough. The Active Inference project can be one such case.
I lack knowledge of the quantity of back and forth traffic between "app" and "model". I think if I had to attack the problem bridgestan was trying to solve, I would have approached it as some sort of RPC thing with language neutrality on the app side - rather than cranking out a bunch of native bindings - invalidate of course if we are slinging K's or M's over the interface
That makes sense. We can at least do that for a proof-of-concept.
Many thanks for looking into this, and I'm sorry that it went complicated.
meh - software does that
And if you are curious about the use cases on the statistics side, I'd be glad to look together.
yes, I'd be interested to see this action
a currently going discussion in the Zulip chat about a topic called Active Inferencefor reference: https://clojurians.zulipchat.com/#narrow/channel/151924-data-science/topic/active.20inference
I need to reincarnate my zulip creds
> yes, I'd be interested to see this action great, I'll write some thoughts later
title it "why not cmdstan"?
then maybe we can solve that problem
Just started a Zulip topic thread on that: https://clojurians.zulipchat.com/#narrow/channel/151924-data-science/topic/why.20not.20cmdstan.3F.20.2F.20do.20we.20need.20bridgestan.3F There, we can keep chatting with a few of the relevant people.