ブログ一覧へ戻るMLOps

DagsHub — オールインワンMLOpsプラットフォーム

💡

DagsHub = GitHub + DVC + MLflow + Label Studio

コード、データ、実験、モデル、コラボレーションを管理するためのオールインワンMLOpsプラットフォームです。


概要

この記事で学べること

  • DagsHubの紹介
  • 環境構築とGit接続
  • DVC(Data Version Control):大規模データのバージョニングとパイプライン
  • DagsHub上のMLflow:experiment trackingとmodel registry
  • デモ:Transformer(HuggingFace)による機械翻訳 EN → VI
  • ベストプラクティスと高度な機能
  • トラブルシューティング

Website

  • https://dagshub.com | 65,000人以上のデータサイエンティストが利用しています

パート1 — DagsHubの紹介

1.1 DagsHubとは?

DagsHubは、Data ScientistとML Engineer向けの包括的なMLOpsプラットフォームです。「Machine LearningのためのGitHub」として構築されており、AI/MLプロジェクトのライフサイクル全体を1つのプラットフォームで管理するために必要なすべてを統合しています。

1.2 なぜDagsHubが必要なのか?

DagsHubが解決する、MLプロジェクトでよくある課題は次のとおりです。

  • Data versioning:通常のGitでは大規模データセットの変更を追跡できません
  • Experiment chaos:多数の実験を実行しても、最良の設定を見つけるのが難しい
  • Model management:モデルを整理して保存・デプロイする場所がない
  • Collaboration:データやモデルファイルを使ったチーム作業が難しい
  • Reproducibility:結果を再現するのが難しい

1.3 主な機能

機能説明
Git RepositoryGitHubと同様にコードを保存し、branches、PRs、issuesに対応
Data Versioning (DVC)大規模データセットを追跡し、S3/GCS/Azure/DagsHub Storageに保存
Experiment TrackingMLflow互換で、metrics、params、artifactsを追跡
Model Registryモデルのバージョンとステージ(Staging/Production)を管理
Data AnnotationLabel Studioを統合し、データのアノテーションに対応
Notebook DiffingJupyter notebooksを視覚的に比較
CI/CD/CTGitHub Actions、GitLab CIと統合
Collaborationリポジトリ、データセット、実験をチームで共有

1.4 他のプラットフォームとの比較

PlatformDagsHub vs ...
GitHubDagsHubはdata versioning、experiment tracking、ML固有の機能を追加します
MLflow (standalone)DagsHubはMLflowサーバーをホストし、さらにGit/DVC統合を提供します
Weights & BiasesDagsHubはオープンソースフレンドリーで、セルフホスト可能、DVCと統合されています
Neptune.aiDagsHubは無料枠がより広く、Git統合がより優れています
DVC StudioDagsHub = DVC Studio + 追加機能(アノテーション、model registry)

パート2 — インストールとセットアップ

2.1 DagsHubアカウントを作成する

  1. https://dagshub.com/user/sign_up にアクセスします
  2. メールで登録するか、GitHub/GitLabアカウントと連携します
  3. メールを確認し、プロフィールを完成させます
  4. GitHubを接続して、既存のリポジトリをインポートすることもできます

2.2 Python環境を構築する

要件:Python >= 3.8、pip または conda

# 仮想環境を作成
python -m venv dagshub_env
source dagshub_env/bin/activate # Linux/Mac
dagshub_env\Scripts\activate # Windows

# 必要なライブラリをインストール
pip install dagshub dvc mlflow torch transformers
pip install sacrebleu sentencepiece datasets

2.3 DagsHubをGitと接続する

# Gitをインストール(未インストールの場合)
git config --global user.name "Your Name"
git config --global user.email "your@email.com"

# DagsHubからリポジトリをクローン
git clone https://dagshub.com/<username>/<repo-name>.git
cd <repo-name>

2.4 Access Tokenを取得する

  1. DagsHubの Settings > Security > Access Tokens に移動します
  2. "Generate new token" をクリックします
  3. トークン名を付け、権限(read/write)を選択します
  4. トークンをコピーし、安全に保管してください(再表示されません)
# ターミナルで認証情報を設定
export DAGSHUB_USER_TOKEN=<your_token> # Linux/Mac
set DAGSHUB_USER_TOKEN=<your_token> # Windows CMD

🔒

セキュリティに関する注意:トークンをGitリポジトリにコミットしないでください。

.env または環境変数を使い、すぐに .env を .gitignore に追加してください。


パート3 — Data Version Control (DVC)

3.1 DVCとは何か、なぜ使うのか?

DVC(Data Version Control)は、大規模データとモデルのバージョン管理を行うオープンソースツールです。Gitと並行して動作します。メタデータはGitに、実際のデータとモデルはリモートストレージに置かれます。

3.2 プロジェクトでDVCを初期化する

# DVCを初期化(git init済みのフォルダ内)
dvc init

# DagsHubをDVCリモートストレージとして設定
dvc remote add origin https://dagshub.com/<username>/<repo>.dvc
dvc remote modify origin --local auth basic
dvc remote modify origin --local user <dagshub_username>
dvc remote modify origin --local password <access_token>

3.3 DVCでデータファイルを追跡する

# データセットをDVCトラッキングに追加
dvc add data/raw/train.csv
dvc add data/raw/test.csv

# メタデータをGitにコミット
git add data/raw/train.csv.dvc data/raw/test.csv.dvc .gitignore
git commit -m "Add training data via DVC"

# データをDagsHubストレージにプッシュ
dvc push

3.4 DVCによるパイプライン

# dvc.yamlにDVCパイプラインのステージを作成
dvc run -n preprocess \
 -d src/preprocess.py -d data/raw/train.csv \
 -o data/processed/train_processed.csv \
 python src/preprocess.py

# パイプライン全体を実行
dvc repro

# パイプラインのDAGを表示
dvc dag

3.5 DagsHubからデータを取得する

# すべてのデータを取得
dvc pull

# 特定バージョンのデータを取得
git checkout <commit-hash>
dvc checkout

パート4 — MLflowによるExperiment Tracking

4.1 MLflowをDagsHubに接続する

DagsHubはリポジトリごとにMLflowサーバーをホストします。別途サーバーをインストールする必要はありません。

import dagshub
import mlflow

# 方法1: dagshub.init()で自動設定
dagshub.init(repo_owner="<username>", repo_name="<repo>", mlflow=True)

# 方法2: 環境変数を手動で設定
import os
os.environ["MLFLOW_TRACKING_URI"] = "https://dagshub.com/<username>/<repo>.mlflow"
os.environ["MLFLOW_TRACKING_USERNAME"] = "<username>"
os.environ["MLFLOW_TRACKING_PASSWORD"] = "<token>"

4.2 基本的な実験を記録する

with mlflow.start_run(run_name="baseline_model"):
	# パラメータを記録
	mlflow.log_param("learning_rate", 0.001)
	mlflow.log_param("batch_size", 32)
	mlflow.log_param("num_epochs", 10)

	# Training loop ...
	for epoch in range(num_epochs):
		train_loss = train_one_epoch(model, data)
		val_bleu = evaluate(model, val_data)

		# 各エポックでメトリクスを記録
		mlflow.log_metric("train_loss", train_loss, step=epoch)
		mlflow.log_metric("val_bleu", val_bleu, step=epoch)

	# モデルアーティファクトを記録
	mlflow.pytorch.log_model(model, "translation_model")

4.3 UIで実験を比較する

  1. DagsHubのリポジトリを開き、「Experiments」タブに移動します
  2. 複数のrunを選択して比較します
  3. メトリクスの時系列グラフを確認します
  4. パラメータやメトリクスでrunをフィルタします
  5. 比較用CSVをダウンロードし、オフラインで分析します

パート5 — デモ:Transformerによる機械翻訳

デモ課題について

  • 課題:テキストを EN → VI に翻訳する
  • Dataset:OPUS / WMT またはカスタムデータセット
  • Model:Transformer(HuggingFaceのHelsinki-NLP/opus-mt-en-vi)
  • Stack:PyTorch + Transformers + DagsHub + MLflow + DVC

5.1 プロジェクト構成

machine_translation/
├── .dvc/ # DVC config
├── data/
│ ├── raw/ # Raw data (tracked by DVC)
│ │ ├── train.csv
│ │ └── test.csv
│ └── processed/ # Processed data
├── src/
│ ├── preprocess.py # Data preprocessing
│ ├── train.py # Training script
│ └── evaluate.py # Evaluation script
├── models/ # Saved models (tracked by DVC)
├── notebooks/ # Jupyter notebooks
├── dvc.yaml # DVC pipeline
├── params.yaml # Hyperparameters
├── requirements.txt
└── README.md

5.2 ステップ1:プロジェクトとDagsHubを初期化する

# 1. DagsHub UIで新しいリポジトリを作成
# 2. ローカルにクローン
git clone https://dagshub.com/<username>/machine-translation.git
cd machine-translation

# 3. DVCを初期化
dvc init
git add .dvc .gitignore
git commit -m "Initialize DVC"

# 4. DVCリモートをセットアップ
dvc remote add -d origin https://dagshub.com/<username>/machine-translation.dvc
dvc remote modify origin --local auth basic
dvc remote modify origin --local user <username>
dvc remote modify origin --local password <token>

5.3 ステップ2:データを準備する(preprocess.py)

# src/preprocess.py
from datasets import load_dataset
import pandas as pd
import os

def prepare_data():
	# HuggingFaceからEN-VIデータセットを読み込む
	dataset = load_dataset("Helsinki-NLP/opus-100", "en-vi")

	# DataFrameに変換
	train_data = []
	for item in dataset["train"]:
		train_data.append({
			"en": item["translation"]["en"],
			"vi": item["translation"]["vi"]
		})

	df = pd.DataFrame(train_data[:50000]) # 5万件のサンプルを取得
	df.to_csv("data/raw/train.csv", index=False)
	print(f"Saved {len(df)} training samples")

if __name__ == "__main__":
	prepare_data()

# 前処理を実行
# python src/preprocess.py
# DVCでデータをトラッキング
# dvc add data/raw/train.csv
# git add data/raw/train.csv.dvc
# git commit -m "Add training dataset"
# dvc push

5.4 ステップ3:トレーニングスクリプト(train.py)

# src/train.py
import dagshub
import mlflow
import torch
from transformers import MarianMTModel, MarianTokenizer
from torch.utils.data import DataLoader, Dataset
import pandas as pd
import yaml

# DagsHubトラッキングを初期化
dagshub.init(
	repo_owner="<username>",
	repo_name="machine-translation",
	mlflow=True
)

# params.yamlからハイパーパラメータを読み込む
with open("params.yaml") as f:
	params = yaml.safe_load(f)

class TranslationDataset(Dataset):
	def __init__(self, df, tokenizer, max_len=128):
		self.src = df["en"].tolist()
		self.tgt = df["vi"].tolist()
		self.tokenizer = tokenizer
		self.max_len = max_len

	def __len__(self):
		return len(self.src)

	def __getitem__(self, idx):
		encoding = self.tokenizer(
			self.src[idx],
			text_target=self.tgt[idx],
			max_length=self.max_len,
			truncation=True,
			padding="max_length",
			return_tensors="pt"
		)
		return {k: v.squeeze() for k, v in encoding.items()}

def train():
	model_name = "Helsinki-NLP/opus-mt-en-vi"
	tokenizer = MarianTokenizer.from_pretrained(model_name)
	model = MarianMTModel.from_pretrained(model_name)

	df = pd.read_csv("data/raw/train.csv")
	dataset = TranslationDataset(df, tokenizer)
	loader = DataLoader(
		dataset,
		batch_size=params["batch_size"],
		shuffle=True
	)

	optimizer = torch.optim.AdamW(
		model.parameters(),
		lr=params["learning_rate"]
	)

	with mlflow.start_run(run_name=params["run_name"]):
		mlflow.log_params(params)

		for epoch in range(params["num_epochs"]):
			model.train()
			total_loss = 0

			for batch in loader:
				outputs = model(**batch)
				loss = outputs.loss
				loss.backward()

				optimizer.step()
				optimizer.zero_grad()
				total_loss += loss.item()

			avg_loss = total_loss / len(loader)
			mlflow.log_metric("train_loss", avg_loss, step=epoch)
			print(f"Epoch {epoch+1}: Loss = {avg_loss:.4f}")

		# モデルを保存して記録
		model.save_pretrained("models/final")
		tokenizer.save_pretrained("models/final")
		mlflow.log_artifacts("models/final", "model")

if __name__ == "__main__":
	train()

5.5 ステップ4:params.yaml

# params.yaml — Hyperparameters
run_name: "transformer_en_vi_v1"
learning_rate: 2e-5
batch_size: 16
num_epochs: 3
max_length: 128
warmup_steps: 500
model_name: "Helsinki-NLP/opus-mt-en-vi"

5.6 ステップ5:評価スクリプト(evaluate.py)

# src/evaluate.py
import mlflow
from transformers import pipeline
from sacrebleu.metrics import BLEU
import pandas as pd

def evaluate_model(model_path, test_file):
	translator = pipeline(
		"translation",
		model=model_path,
		device=-1
	) # CPU

	df = pd.read_csv(test_file)
	bleu = BLEU()

	predictions = []
	references = []

	for _, row in df.head(500).iterrows():
		pred = translator(row["en"])[0]["translation_text"]
		predictions.append(pred)
		references.append([row["vi"]])

	score = bleu.corpus_score(predictions, references)
	print(f"BLEU Score: {score.score:.2f}")

	with mlflow.active_run():
		mlflow.log_metric("bleu_score", score.score)

	return score.score

5.7 ステップ6:DVC Pipeline(dvc.yaml)

# dvc.yaml
stages:
	preprocess:
		cmd: python src/preprocess.py
		deps:
			- src/preprocess.py
		outs:
			- data/raw/train.csv
	train:
		cmd: python src/train.py
		deps:
			- src/train.py
			- data/raw/train.csv
			- params.yaml
		params:
			- learning_rate
			- batch_size
			- num_epochs
		outs:
			- models/final
		metrics:
			- metrics/train_metrics.json
	evaluate:
		cmd: python src/evaluate.py
		deps:
			- src/evaluate.py
			- models/final
			- data/raw/test.csv
		metrics:
			- metrics/eval_metrics.json:
					cache: false

# パイプライン全体を実行
# dvc repro

5.8 ステップ7:異なる設定で実験を実行する

# 別の学習率を試す
dvc exp run --set-param learning_rate=5e-5

# 別のバッチサイズを試す
dvc exp run --set-param batch_size=32

# 実験を比較
dvc exp show

# 実験をDagsHubにプッシュ
dvc exp push origin

パート6 — Model Registry

6.1 トレーニング後にモデルを登録する

import mlflow

# モデルをレジストリに登録
run_id = mlflow.last_active_run().info.run_id
model_uri = f"runs:/{run_id}/model"

mlflow.register_model(
	model_uri=model_uri,
	name="en-vi-transformer"
)

6.2 モデルのステージを管理する

from mlflow.tracking import MlflowClient

client = MlflowClient()

# モデルをStagingに移行
client.transition_model_version_stage(
	name="en-vi-transformer",
	version=1,
	stage="Staging"
)

# テストが問題なければProductionに昇格
client.transition_model_version_stage(
	name="en-vi-transformer",
	version=1,
	stage="Production"
)

6.3 Registryからモデルを読み込んで推論する

# Productionステージからモデルを読み込む
model = mlflow.pyfunc.load_model(
	model_uri="models:/en-vi-transformer/Production"
)

# Inference
result = model.predict(["Hello, how are you?"])
print(result) # [("Xin chào, bạn có khỏe không?")]

パート7 — コラボレーションとベストプラクティス

7.1 DagsHubでのチーム作業

  • プライベートリポジトリを作成し、Settings > Members からコラボレーターを招待します
  • 実験や機能ごとにブランチを使います
  • マージ前にコードと実験をレビューするため、Pull Requestsを作成します
  • Issuesを使ってバグ、ToDo、議論を追跡します
  • PR内で実験を比較し、改善点が明確に分かるようにします

7.2 .gitignore と .dvcignore

# .gitignore — Gitにプッシュしないもの
__pycache__/
- .pyc
.env
models/
data/raw/
data/processed/
- .log

# .dvcignore — DVCが無視するもの
.git
- .pyc
__pycache__

7.3 GitHub ActionsによるCI/CD

# .github/workflows/train.yml
name: Train and Evaluate

on:
	push:
		branches: [main]
		paths: [src/**, params.yaml]

jobs:
	train:
		runs-on: ubuntu-latest
		steps:
			- uses: actions/checkout@v3

			- name: Setup Python
				uses: actions/setup-python@v4
				with: { python-version: "3.10" }

			- name: Install dependencies
				run: pip install -r requirements.txt

			- name: Pull data from DagsHub
				env:
					DAGSHUB_TOKEN: $ secrets.DAGSHUB_TOKEN 
				run: dvc pull

			- name: Run pipeline
				run: dvc repro

7.4 ベストプラクティス

カテゴリベストプラクティス
Namingrunには意味のある名前を付けます:"transformer_lr2e5_bs16_epoch3"
Paramsハイパーパラメータはハードコードせず、常にparams.yamlを使います
Tagging実験にversion、dataset、architectureのタグを付けます
Metrics最後だけでなく、各エポックでメトリクスを記録します
Artifactsモデル、tokenizer、confusion matrixも記録します
Reproducibilityrandom seedを設定し、paramとして記録します
Documentation各experiment runに十分な説明を記入します
Data lineageモデルを、学習に使ったデータセットのバージョンと常に紐付けます

パート8 — 高度な機能

8.1 DagsHub Storage API(S3互換)

import boto3

s3 = boto3.client(
	"s3",
	endpoint_url="https://dagshub.com/s3",
	aws_access_key_id="<username>",
	aws_secret_access_key="<token>"
)

# ファイル一覧を取得
response = s3.list_objects(Bucket="<username>/<repo>")

# ファイルをアップロード
s3.upload_file(
	"local_file.csv",
	"<username>/<repo>",
	"path/in/repo.csv"
)

8.2 DagsHub Dataset Streaming

import dagshub.data_engine as de

# データセットに接続
ds = de.init("<username>/<repo>", "data/raw")

# クエリとフィルタ
filtered = ds.filter(lambda x: x.file_size > 1000)\
	.select(["filename", "label", "split"])

# 必要なファイルだけをダウンロード
filtered.download()

8.3 DVC Experimentsによるハイパーパラメータ探索

# グリッドサーチを実行
dvc exp run --queue \
 --set-param learning_rate=1e-5 \
 --set-param batch_size=16

dvc exp run --queue \
 --set-param learning_rate=2e-5 \
 --set-param batch_size=32

dvc exp run --queue \
 --set-param learning_rate=5e-5 \
 --set-param batch_size=64

# キューに入ったすべての実験を実行(並列)
dvc queue start --jobs 3

8.4 HuggingFace向けのカスタムMLflow Callbacks

from transformers import TrainerCallback
import mlflow

class DagsHubCallback(TrainerCallback):
	def on_log(self, args, state, control, logs=None, **kwargs):
		if state.is_local_process_zero and logs:
			for k, v in logs.items():
				if isinstance(v, (int, float)):
					mlflow.log_metric(k, v, step=state.global_step)

# HuggingFace Trainerで使用
trainer = Seq2SeqTrainer(
	model=model,
	args=training_args,
	train_dataset=train_dataset,
	eval_dataset=eval_dataset,
	callbacks=[DagsHubCallback()]
)

8.5 NotebookのバージョニングとDiffing

  • Jupyter notebooksを通常のコードと同じようにDagsHubへプッシュします
  • DagsHubはnotebookの見やすいdiff(セル単位)を表示します
  • 出力の変更、メトリクスの変更、コードの変更を分けて確認できます
  • Pull Requestsでnotebookをレビューする際に特に便利です

パート9 — Tips、Tricks、トラブルシューティング

9.1 よくあるエラーと対処法

エラー解決策
dvc push: 403 Forbiddenトークンを再確認し、write permissionがあることを確認してください
MLflow: Cannot connectMLFLOW_TRACKING_URIを確認し、先にdagshub.init()を実行してください
dvc pull: No data最新の.dvcファイルを得るため、先にgit pullを実行してください
Large model push slow並列アップロードのため dvc push --jobs 4 を使ってください
Experiment not showingmlflow.end_run()が呼ばれていること、またはコンテキストマネージャを使っていることを確認してください

9.2 役立つTips

  • MLflowのtagsで実験をグループ化します:mlflow.set_tag("model_type", "transformer")
  • システムメトリクスを自動記録します:mlflow.autolog()
  • dvc metrics show を使い、ターミナル上でメトリクスを確認します
  • .dvc/config でdefault remoteを設定し、毎回指定しなくて済むようにします
  • DagsHub Organizationを作成し、チームのリポジトリをより適切に管理します
  • DagsHub Webhooksを使い、実験完了時にアクションをトリガーします

9.3 MLプロジェクトの最適なワークフロー

  1. DagsHubでリポジトリを作成 → clone → dvc init
  2. データを準備 → dvc add → dvc push → git commit
  3. コードを書く → トレーニングスクリプト内で dagshub.init()
  4. dvc exp run で実験を実行 → UIで比較
  5. 最良のモデルを登録 → Productionに昇格
  6. PRを作成 → 実験結果をレビュー → merge

9.4 さらに学ぶためのリソース

  • 公式ドキュメント:https://dagshub.com/docs
  • DagsHub Blog:https://dagshub.com/blog — 実践的なチュートリアルが豊富です
  • YouTube:DagsHubチャンネルにビデオチュートリアルがあります
  • GitHub:https://github.com/DAGsHub — オープンソースツール
  • Discord community:DagsHubチームとコミュニティに質問できます
Huỳnh Phước Nguyên

執筆 Huỳnh Phước Nguyên

AIエンジニア、BK Hightech

一緒に、優れたプロダクトを作りませんか?

プロジェクトについてお聞かせください。1営業日以内にご連絡いたします。

お問い合わせ