はじめに
これは、Pythonを使っている全ユーザー(特に、notebookでデータ分析をやっている方)に使って欲しいパッケージです。ぜひ、インストールして使ってみてください。
SessionSmithとは
SessionSmithは、python notebook等でのセッション(変数や型)を管理するPython Packageです。Google Colab等では、一定期間触れないとランタイムの切断となってしまい再度実行し直す必要があります。また、機械学習等では、pickle等を使ってモデルを保存することもできます。しかし、保存したファイル名で、どの環境で構築したものを区別するか管理するのは、あまり適していないように思えます。なんなら、Gitのようにブランチを分け、Aの環境で構築した場合, Bの環境で構築した場合のように別々に管理できるようした方が得策だと考え、Git風セッション管理パッケージであるSessionSmithを開発しました。
基本的な使い方
セッション管理の初期化(init)
まずは、Gitでのgit initと同じように、プロジェクトディレクトリにてセッション管理を始めるために初期化する必要があります。以下のコードで実行してみましょう。
# ライブラリをインポート
from SessionSmith import ssm
# 初期化
ssm.init()
このようにすると、以下のような.ssmというディレクトリが作成されるかと思います。
.ssm下の各ディレクトリについては後々説明していきます。基本的に、SessionSmithを通してnotebook, cliから確認できるので、中身を見ることはないかと思います。
セッションの記録(commit)
次はセッションを記録する方法です。スナップショットを撮るように、そのランタイム上にある変数をセッションとして記録できます。Gitでは、git commit -m "コミットメッセージ"というようなコードですね。
# 変数の定義
a = 1
# 変更した変数のコミット
ssm.commit("commit message")
コミット履歴の表示
セッションを記録(コミット)において、いつ誰がどの型として保存しているか確認できます。
# 履歴を表示
ssm.log()
実行すると、以下のように表示できるでしょう。
前のコミット状態に戻す
コミットをしていれば、その状態に戻すことができます。Gitの場合は、git reset --hard [コミットid]でできることと同じです。
※ git checkout とは動作が異なることに注意してください。
a = 1
print(a)
# 1
ssm.commit("defined a")
a = 2
print(a)
# 2
ssm.commit("changed a")
# ssm.log()を実行して、"defined a"のコミットハッシュを取得
ssm.checkout("defined aのコミットハッシュ")
print(a)
# 1
ただし、最新のコミットに戻る場合は、引数なし(ssm.checkout())で実行できます。
現状の確認
現在、どの変数が定義されているか確認するコードとして、status()が用意されています。
a = 1
b = 2
ssm.status()
実行結果はこのようになるでしょう。a, bがint型で定義されていることがわかります。
応用的な使い方1: アルゴリズムトレーサー
アルゴリズムを勉強している際にいつどこで変数が変化するか, なぜクラッシュしたのかを記録したいと思った時はないでしょうか。普通なら、print()で変数を繰り返し表示したり、pythonライブラリのicecreamを使うのもありです。ただし、どちらも表示するコードをいちいち書く必要があり、記録することはできません(リストにするとかもありではあるが、コードを書くことは変わらない)。そこで、SessionSmithのアルゴリズムトレーサーの出番です。使い方を見ていきましょう。
from SessionSmith import AlgorithmTracer, print_trace_summary
# バブルソートをトレース
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(0, n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
# トレース対象の配列
arr = [64, 34, 25, 12, 22, 11, 90]
print(f"ソート前: {arr}")
# トレーサーを使用
with AlgorithmTracer(target_variables=["arr"]) as tracer:
result = bubble_sort(arr)
print(f"ソート後: {result}")
print(f"\nトレースポイント数: {len(tracer.get_trace_data())}")
これを実行すると、以下のように表示されるでしょう。
では、トレースした中身を確認してみましょう。
import matplotlib
from SessionSmith import visualize_algorithm_trace
# 可視化(matplotlibがインストールされている場合)
try:
visualize_algorithm_trace(
trace_data=tracer.get_trace_data(),
output_file="temp/bubble_sort_animation.svg",
target_variables=["arr"],
animation=True,
show=False
)
print("✓ アニメーションを保存しました: temp/bubble_sort_animation.svg")
except ImportError:
print("matplotlibがインストールされていないため、可視化をスキップします")
print("インストール: pip install matplotlib")
except Exception as e:
print(f"可視化中にエラーが発生しました: {e}")
そうすると、以下のような.htmlファイルが生成されると思います。ですので、右クリックしてLiveServerで開いてみましょう。
※ Live Serverは、htmlファイルを見る時に便利な拡張機能です。htmlファイルが変更されると自動でビューも変わります。
簡単に動画を見たい方は、こちらをご参照ください。
応用的な使い方2: 常時記録
次に、応用的な使い方を確認しましょう。コードを実行している時にクラッシュして再度実行した経験はないでしょうか。そこで、SessionSmithでは、クラッシュするまでの変数の移り変わりを記録し、クラッシュ寸前に戻すことができるような機能を提供しています。
# 常時記録の開始
ssm.continuous(enable= True)
# アルゴリズムのコード(クラッシュする場合でもOK)
# クラッシュしたら、以下を実行
ssm.recover()
応用的な使い方3: 長時間記録用トレーサー
機械学習, 深層学習の学習時には、ものすごい時間を要する場合があります。そのため、途中で意図しない停止, クラッシュなどがあると、絶望ですよね。try, exceptなどを入れていても、セッションが再起動されては太刀打ちできません。そこで、長時間実行時に定期的にセッションを記録(コミット)してくれる機能がSessionSmithにはあります。
from SessionSmith import ssm
ssm.init()
# 5分ごとに自動チェックポイント
with ssm.checkpoint(interval=300) as cp:
for epoch in range(1000):
loss = train_one_epoch()
acc = validate()
# 手動チェックポイント + メトリクス記録
cp.step(loss=loss, accuracy=acc, epoch=epoch)
ssm.checkpoint()のパラメータは以下の通りです。
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
interval |
int | 300 | チェックポイント間隔(秒) |
max_checkpoints |
int | 5 | 保持するチェックポイント数 |
on_error |
str | "warn" | エラー時の動作("ignore", "warn", "raise") |
compress |
bool | True | 圧縮するか |
message |
str | "Checkpoint" | チェックポイントメッセージ |
中断した場合は、以下のコードで再開できます。
# 前回の状態を復元
try:
meta = ssm.restore_checkpoint()
start_epoch = epoch + 1
except FileNotFoundError:
start_epoch = 0
model = create_model()
# 学習を再開/開始
with ssm.checkpoint(interval=300) as cp:
for epoch in range(start_epoch, 100):
train()
cp.step(epoch=epoch)
さいごに
機能改善は今後も続けていきたいと思っておりますので、欲しい機能, 改善案等ございましたら、GitHub Issuesの方に上げてくださると嬉しいです。まだまだ未熟な部分ありますので、ご指摘いただけると励みになります。読んでくださり、ありがとうございました!!
参考




