コース進捗 コース目次 34レッスン中 34件を公開中
第0部―まず地図を広げる
第1部―簡単な目的で、なぜ動画が分かるのか
第2部―一本の動画を一台のエンコーダーへ
第3部―実験を読めてこそ、論文を読んだと言える
第4部―公式リポジトリから自分の実験へ
第5部―表現を世界モデル構想へ戻す
付録―必要なときに開く技術リュック
箱を開ける前の五つの確認
- コードを読む外部の Python が動く
- 版を留める重みと実装を一組に
- 軸を並べる
B,C,T,H,W - 値を整えるImageNet の平均と標準偏差
- 特徴を受け取る小片か要約札か
動いた、だけでは足りない
借りた顕微鏡に標本を裏返して置いても、何かしらの像は見えます。動画モデルも同じです。時間と色の軸を取り違えてなお計算が通る場合があり、もっともらしい無意味な数値が返ってきます。最初の成功条件は「例外が出なかった」ではなく、版、入力、出力を一つずつ照合できたことです。
公開重みの身元
公開されている LeVJEPA-VideoMix-Largeは ViT-L/16、303.1M パラメータです。モデルカードによれば、1,806,869 本の VideoMix 標本で学習されました。入力は16フレーム、空間パッチは16×16、tubelet の時間幅は1、位置表現は RoPE、注意方式は block_causal です。
Hugging Face から読むときは trust_remote_code=True が必要です。これは設定だけでなく、配布元の Python コードを手元で実行する指定です。まず config.json、configuration_levjepa.py、modeling_levjepa.py を読み、ネットワーク通信、環境変数の参照、動的な文字列実行がないかを調べます。機密情報を置かない隔離環境で試し、浮動する最新版ではなく、本講座で確認したモデル版 e831a0347737fcaa660b39c57d41c109de399845 を固定します。
重みが safetensors であることと、ライセンスも別々に確認します。モデルカード上の重みは CC BY-NC 4.0です。技術的に読み込めることは、商用利用できることを意味しません。
最小の特徴抽出
import torch
from transformers import AutoModel
repo = "galilai-group/LeVJEPA-VideoMix-Large"
revision = "e831a0347737fcaa660b39c57d41c109de399845"
model = AutoModel.from_pretrained(
repo,
revision=revision,
trust_remote_code=True,
).eval()
# raw は [0, 1]。実動画は先に 224×224 へ同じ方法で変換する。
raw = torch.rand(1, 3, 16, 224, 224) # [B,C,T,H,W]
mean = raw.new_tensor([0.485, 0.456, 0.406])[None, :, None, None, None]
std = raw.new_tensor([0.229, 0.224, 0.225])[None, :, None, None, None]
video = (raw - mean) / std
with torch.inference_mode():
out = model(pixel_values=video)
print(out.last_hidden_state.shape)
print(out.pooler_output.shape)
期待する形は次の二つです。
last_hidden_state: [1, 3137, 1024]
pooler_output: [1, 1024]
3137 = 1 + 16×14×14。先頭の一つが [CLS]、残りが16時刻×14行×14列のパッチ特徴です。評価時にはトークンを落とさないため、学習時の疎な長さ158ではなく全3137個が戻ります。pooler_output は [CLS] の埋め込みであり、分類確率ではありません。公開モデルに分類頭はありません。
次の検査もその場で加えます。
assert out.last_hidden_state.shape == (1, 3137, 1024)
assert out.pooler_output.shape == (1, 1024)
assert torch.isfinite(out.last_hidden_state).all()
assert model.config.attn_mode == "block_causal"
同じ入力を二度通した出力が、使った機器の数値誤差内で一致することも確かめます。GPU や MPS に移すなら、モデル、入力、平均、標準偏差を同じ装置へ置きます。全トークンの ViT-L は記憶量を使うので、まず標本数1から始めます。足りないからと注意方式を full に替えると、動いても元の学習条件とは別物です。
学習時の標本化はおよそ7.5 fps なので、16フレームは約2秒を覆います。一枚の静止画を16回繰り返す使い方は、静止画の特徴を見る便法にはなります。ただし、そこに運動情報はありません。公開された重みは評価用に平滑化されたエンコーダーで、教師枝でも、学習時の投影器込みのモデルでもありません。
出典を固定する
三枚の安全札
trust_remote_code=Trueは外部コードを実行するので、内容を読み、版を固定します。- 入力は ImageNet 正規化済みの
[B,C,T,H,W]、既定では16×224×224です。 - 出力は特徴であって分類結果ではなく、公開重みは評価用の EMA 複製です。
開封確認
- 出力トークンが3137個になる内訳は何ですか。
- 記憶不足を理由に
full注意へ替えても、元と同じ推論と呼べますか。 pooler_outputをそのまま ImageNet の確率として読めますか。
答えを確かめる
[CLS]一つと、16時刻×14行×14列のパッチ3136個です。- 呼べません。計算は通っても、学習時の情報の流れを変えています。
- 読めません。1024次元の
[CLS]埋め込みで、分類頭はありません。