Afin de lire "Modélisation statistique Bayes avec Stan et R", j'ai préparé un environnement CmdStanPy avec docker. Il semblait y avoir peu de documents japonais sur la construction de l'environnement pour CmdStanPy, donc je pense que cela pourrait être utile pour quelqu'un, alors je vais l'écrire.
Comme vous pouvez le voir dans le Document officiel, veuillez faire attention si vous utilisez un environnement où PyStan est déjà installé.
Note for PyStan users: PyStan and CmdStanPy should be installed in separate environments. If you already have PyStan installed, you should take care to install CmdStanPy in its own virtual environment.
J'ai préparé l'environnement avec docker car il semble gênant en raison d'autres problèmes de dépendance [^ 1].
L'emballage léger de CmdStan par Python
Si vous voulez utiliser Stan depuis Python, vous utiliserez probablement PyStan en général [^ 2]. Donc, la raison pour laquelle j'ai décidé d'utiliser CmdStanPy est qu'il fonctionne plus rapidement (actuellement) que PyStan.
Les détails sont les suivants:
J'ai également préparé un environnement PyStan au début, mais avec un exemple simple appelé Eight schools (voir cette partie du document PyStan). Il a fallu plus d'une minute pour compiler mon modèle.
Après avoir vérifié si ma méthode d'installation était mauvaise ou normale, [cet échange] dans la communauté de Stan (https://discourse.mc-stan.org/t/why-is-it) -so-slow-for-stan-to-compile-model / 6004) a été trouvé. Selon
Stan compilation speedup was introduced in Stan 2.20, but Rstan is only up to Stan 2.19.2.
right now we have lightweight wrappers CmdStanPy 11 (still in beta) and CmdStanR 18 (almost to beta release) which use the latest CmdStan (now at 2.21, 2.22 coming soon) - or any version of CmdStan that you’d like.
Cet échange lui-même remonte à deux ans, mais quand j'ai vérifié la version de PyStan dans mon environnement PyStan, c'était la 2.19.1.1, qui semblait être celle avant l'introduction de speedup [^ 3]. De plus, même en écrivant Stackoverflow ici, CmdStanPy a rendu la compilation plus de 3 fois plus rapide. Il y avait une description.
J'ai donc décidé d'essayer CmdStanPy.
Dockerfile
FROM ubuntu:20.04
RUN apt-get -y update
RUN apt-get -y install python3
RUN apt-get -y install python3-pip
RUN pip3 install --upgrade pip
RUN pip3 install cmdstanpy[all]
RUN python3 -c 'import cmdstanpy; cmdstanpy.install_cmdstan()'
WORKDIR /workdir
Construisez comme suit dans le répertoire où se trouve ce Dockerfile [^ 4](remplacez YOUR_TAG par un nom de TAG approprié),
docker image build -t YOUR_TAG .
Démarrer (je monte le répertoire actuel sur / workdir
parce que je veux utiliser le code source local)
docker container run -it --rm --net=host \
--mount type=bind,src=`pwd`,dst=/workdir \
YOUR_TAG \
bash
Dans le répertoire où vous avez démarré le conteneur Docker
8schools.stan
[^5])8schools.data.json
)run-cmdstanpy.py
)Je vais préparer.
8schools.stan
data {
int<lower=0> J; // number of schools
vector[J] y; // estimated treatment effects
vector<lower=0>[J] sigma; // s.e. of effect estimates
}
parameters {
real mu;
real<lower=0> tau;
vector[J] eta;
}
transformed parameters {
vector[J] theta;
theta = mu + tau * eta;
}
model {
eta ~ normal(0, 1);
y ~ normal(theta, sigma);
}
JSON:8schools.data.json
{
"J": 8,
"y": [28, 8, -3, 7, -1, 1, 18, 12],
"sigma": [15, 10, 16, 11, 9, 11, 10, 18]
}
run-cmdstanpy.py
from cmdstanpy import CmdStanModel
print("Compile started")
model = CmdStanModel(stan_file="8schools.stan")
print("Compile finished")
print(model)
print("========================================")
data = "8schools.data.json"
print("Sampling started")
fit = model.sample(data=data)
print("Sampling finished")
print(fit)
Si vous exécutez python3 run-cmdstanpy.py
dans / workdir
dans le conteneur démarré dans la section" Construction de l'environnement avec Docker "et obtenez le résultat suivant, cela réussit pour le moment.
Compile started
INFO:cmdstanpy:compiling stan program, exe file: /workdir/8schools
INFO:cmdstanpy:compiler options: stanc_options=None, cpp_options=None
INFO:cmdstanpy:compiled model file: /workdir/8schools
Compile finished
CmdStanModel: name=8schools
stan_file=/workdir/8schools.stan
exe_file=/workdir/8schools
compiler_optons=stanc_options=None, cpp_options=None
========================================
Sampling started
INFO:cmdstanpy:start chain 1
INFO:cmdstanpy:start chain 2
INFO:cmdstanpy:start chain 3
INFO:cmdstanpy:start chain 4
INFO:cmdstanpy:finish chain 3
INFO:cmdstanpy:finish chain 1
INFO:cmdstanpy:finish chain 4
INFO:cmdstanpy:finish chain 2
Sampling finished
CmdStanMCMC: model=8schools chains=4['method=sample', 'algorithm=hmc', 'adapt', 'engaged=1']
csv_files:
/tmp/tmpd0ii4fo_/8schools-202009110125-1-0qknvwdc.csv
/tmp/tmpd0ii4fo_/8schools-202009110125-2-qfoj4mom.csv
/tmp/tmpd0ii4fo_/8schools-202009110125-3-cbn8wxph.csv
/tmp/tmpd0ii4fo_/8schools-202009110125-4-h_5980t6.csv
output_files:
/tmp/tmpd0ii4fo_/8schools-202009110125-1-0qknvwdc-stdout.txt
/tmp/tmpd0ii4fo_/8schools-202009110125-2-qfoj4mom-stdout.txt
/tmp/tmpd0ii4fo_/8schools-202009110125-3-cbn8wxph-stdout.txt
/tmp/tmpd0ii4fo_/8schools-202009110125-4-h_5980t6-stdout.txt
deleting tmpfiles dir: /tmp/tmpd0ii4fo_
done
Pour plus de détails sur l'utilisation de CmdStanPy, voir Document officiel.
Je vais également enregistrer brièvement la comparaison de vitesse avec PyStan. Tous les fichiers stan sont communs à 8schools.stan
écrits dans la section" Exécution ".
CmdStanPy
L'environnement Docker est décrit dans "Création d'un environnement avec Docker". J'ai utilisé le fichier python suivant:
test-cmdstanpy.py
from cmdstanpy import CmdStanModel
import time
print("Compile started")
t1 = time.time()
model = CmdStanModel(stan_file="8schools.stan")
t2 = time.time()
data = "8schools.data.json"
print("Sampling started")
t3 = time.time()
fit = model.sample(data=data)
t4 = time.time()
print("Compile time :", t2 - t1, "seconds")
print("Sampling time :", t4 - t3, "seconds")
PyStan
Le Dockerfile utilisé est le suivant:
Dockerfile
FROM ubuntu:20.04
RUN apt-get -y update
RUN apt-get -y install python3
RUN apt-get -y install python3-pip
RUN pip3 install --upgrade pip
RUN pip3 install pystan
WORKDIR /workdir
Construisez et démarrez de la même manière que "Créer un environnement avec Docker". En outre, le fichier python utilisait ce qui suit. ::
test-pystan.py
import pystan
import time
schools_dat = {'J': 8,
'y': [28, 8, -3, 7, -1, 1, 18, 12],
'sigma': [15, 10, 16, 11, 9, 11, 10, 18]}
print("Compile started")
t1 = time.time()
sm = pystan.StanModel(file='8schools.stan')
t2 = time.time()
print("Sampling started")
t3 = time.time()
fit = sm.sampling(data=schools_dat, iter=1000, chains=4)
t4 = time.time()
print("Compile time :", t2 - t1, "seconds")
print("Sampling time :", t4 - t3, "seconds")
CmdStanPy
Compile time : 12.916020393371582 seconds
Sampling time : 0.16101527214050293 seconds
PyStan
Compile time : 98.87509870529175 seconds
Sampling time : 0.45189523696899414 seconds
Je l'ai mesuré plusieurs fois, mais quand il s'agissait de compiler le modèle, le résultat était que CmdStanPy était fondamentalement environ 7 fois plus rapide que PyStan [^ 6] [^ 7].
[^ 1]: Cependant, puisque j'utilise docker dans une atmosphère, la méthode de construction de l'environnement docker décrite ici n'est peut-être pas la meilleure. [^ 2]: Le document et la page github de PyStan ont été les premiers à apparaître dans une recherche Google pour "Python Stan". C'était (: //github.com/stan-dev/pystan). [^ 3]: Est-ce la reconnaissance que le numéro de version PyStan correspond au numéro de version Stan ...? [^ 4]: Voir https://cmdstanpy.readthedocs.io/en/latest/getting_started.html#installation pour plus de détails sur la partie qui installe CmdStanPy. [^ 5]: Téléchargé depuis la page de démarrage de PyStan. Https://pystan.readthedocs.io/en/latest/getting_started.html [^ 6]: Dans le cas de CmdStanPy, il y a une fonction sympa qui "compare l'heure de modification du fichier exe et du fichier stan, et si ce dernier est plus récent que le premier, il ne se compilera pas", donc soyez prudent lorsque vous mesurez à plusieurs reprises .. [^ 7]: Lorsque l'image de base de PyStan était définie sur ubuntu: 16.04, PyStan a également pris environ 50 secondes, mais la cause n'a pas été étudiée.