AI Model Versioning: Git & DVC for 2026

Listen to this article · 13 min listen

Effective AI model versioning is no longer a luxury. It’s a fundamental requirement for reproducible and scalable machine learning operations. Data scientists and MLOps engineers often grapple with tracking not just code changes, but also the specific datasets and model artifacts that produced a given result. Without a systematic approach, recreating past experiments or deploying previous model iterations becomes a chaotic, time-consuming endeavor, prone to errors. This article details a practical, step-by-step walkthrough for implementing strong AI model versioning using Git for code and DVC (Data Version Control) for data and models, ensuring your projects remain organized and auditable.

Key Takeaways

  • Configure DVC to store large files in remote storage like AWS S3 or Google Cloud Storage, linking them to your Git repository for complete version control.
  • Use dvc add to track datasets and trained model files, creating lightweight .dvc files that Git then manages.
  • Commit both code changes and .dvc file updates in Git, establishing a single source of truth for your entire ML project state.
  • Use dvc checkout and git checkout in tandem to effortlessly revert to any previous state of your code, data, and models.
  • Implement DVC pipelines with dvc run to automate the tracking of data dependencies and model generation steps, ensuring reproducibility.

1. Initialize Your Project with Git and DVC

The first step involves setting up your project with both Git and DVC. Git will handle your code versioning, while DVC will manage your large datasets and trained model binaries. This dual approach ensures that your entire machine learning experiment, from data preprocessing scripts to the final model weights, is versioned coherently.

Open your terminal and navigate to your project directory. If you don’t have one, create it. For instance, mkdir my_ml_project && cd my_ml_project. Then, initialize a Git repository:

git init

Next, initialize DVC within the same directory:

dvc init

This command creates a .dvc directory, which stores DVC’s internal files, and modifies your .gitignore file to exclude DVC cache directories. An important aspect of this setup is DVC’s ability to integrate smoothly with Git. It doesn’t store large files directly in Git. Instead, it stores metadata about them and links them to a remote storage location. This keeps your Git repository lean and efficient, avoiding the performance bottlenecks associated with large binary files.

Pro Tip: Always initialize Git first, then DVC. DVC automatically detects the Git repository and configures itself for integration. This order simplifies the initial setup significantly.

2. Configure Remote Storage for DVC

DVC manages large files by storing them in a dedicated remote storage location, often cloud-based, and only committing lightweight pointer files to Git. This separation is key to maintaining a performant Git repository. You need to configure this remote storage before you start tracking data. Common choices include Amazon S3, Google Cloud Storage, Azure Blob Storage, or even local network storage.

Let’s assume you’re using AWS S3. First, ensure you have your AWS credentials configured, typically via environment variables or the AWS CLI. Then, add the remote:

dvc remote add -d storage s3://your-bucket-name/dvc-store

Replace your-bucket-name/dvc-store with the actual path to your S3 bucket and a desired subdirectory for DVC’s cache. The -d flag sets this as the default remote. For Google Cloud Storage, the command would look similar:

dvc remote add -d storage gs://your-gcs-bucket/dvc-store

DVC then updates your .dvc/config file with this information. This configuration tells DVC where to push and pull the actual data files when you use commands like dvc push or dvc pull. Without this, DVC wouldn’t know where to store your large files, rendering its versioning capabilities incomplete. I’ve seen teams struggle for days because they missed this critical step. Their Git repo was clean, but their data wasn’t backed up anywhere.

Common Mistake: Forgetting to configure appropriate access permissions for your DVC remote. Ensure the IAM user or service account associated with your environment has read and write access to the specified S3 bucket or GCS bucket. A common error message will indicate “Access Denied” during dvc push if permissions are incorrect.

3. Track Your Datasets with DVC

Now that your remote storage is configured, you can start tracking your raw datasets. Imagine you have a CSV file named data/raw_data.csv that’s several gigabytes in size. You wouldn’t want to commit this directly to Git.

Use the dvc add command to track it:

dvc add data/raw_data.csv

When you run this, DVC does a few things: it moves the actual raw_data.csv file into its local cache (typically in .dvc/cache), replaces the original file with a small data/raw_data.csv.dvc file, and generates a hash for the file’s content. The .dvc file is a plain text file containing metadata about the original file, including its path, hash, and the remote location where it’s stored. This .dvc file is what you commit to Git.

After adding the file, you’ll see the new .dvc file. Now, add and commit it to Git:

git add data/raw_data.csv.dvc .gitignore
git commit -m "Add raw_data.csv and DVC config"

Finally, push the actual data to your configured remote storage:

dvc push

This command uploads the content of raw_data.csv (from DVC’s local cache) to your S3 or GCS bucket. The beauty here is that Git only sees the tiny .dvc pointer file, while DVC handles the heavy lifting of storing and retrieving the actual data.

Pro Tip: Track entire directories of data using dvc add data/. DVC will recursively track all files within that directory, creating a single data.dvc file that represents the entire directory’s state. This is especially useful for managing large collections of images or text files.

4. Version Your Trained Models

Just as you version your input data, you must version your trained machine learning models. A model is an artifact of your training process, and its performance is directly tied to the code and data used to create it. Let’s say you’ve trained a model and saved its weights to models/my_model_v1.pkl.

Track this model artifact with DVC:

dvc add models/my_model_v1.pkl

This creates a models/my_model_v1.pkl.dvc file. Now, you need to commit this pointer file to Git, along with any code changes that led to this model’s creation. For example, if you updated your training script src/train.py:

git add models/my_model_v1.pkl.dvc src/train.py
git commit -m "Train initial model v1 with updated script"

And remember to push the actual model file to your remote storage:

dvc push

This workflow establishes a clear link between your code, the data it was trained on (via the raw_data.csv.dvc file), and the resulting model. If you later train my_model_v2.pkl, you’d repeat this process, adding the new model with DVC and committing its .dvc file to Git. This allows you to reconstruct the exact state of your project at any given commit, including the specific model used.

Common Mistake: Forgetting to push the DVC cache to the remote. If you only commit the .dvc file to Git but don’t run dvc push, the actual data or model file will only exist in your local DVC cache. Other team members or your CI/CD pipeline won’t be able to retrieve it, leading to “file not found” errors when they try to dvc pull.

5. Revert to Previous Model Versions

One of the most powerful features of combining Git and DVC is the ability to smoothly revert to any previous state of your entire project, including specific data and model versions. This is invaluable for debugging, reproducing results, or rolling back to a known good state.

Suppose you’ve made some changes, trained a new model, and committed everything. Now you want to go back to the state where you trained my_model_v1.pkl. First, identify the Git commit hash associated with that version.

git log, oneline

Let’s say the commit hash was a1b2c3d. To revert, you perform a Git checkout, followed by a DVC checkout:

git checkout a1b2c3d
dvc checkout

The git checkout command reverts your code (including the .dvc pointer files) to the specified commit. The subsequent dvc checkout command then reads the .dvc files at that commit and restores the corresponding data and model files from DVC’s cache or, if not present locally, pulls them from your remote storage. Your project directory will now contain the exact code, data, and model artifacts that existed at commit a1b2c3d.

This process is far more efficient than manually managing multiple copies of large files, which inevitably leads to confusion and wasted storage. It’s a non-negotiable practice for any serious ML engineering team. I’ve personally used this to debug production issues, identifying exactly which data shift led to a model’s performance degradation by stepping through versions.

Pro Tip: Use Git tags for major model versions. Instead of remembering commit hashes, you can tag a specific Git commit with a descriptive name, like git tag -a v1.0.0_model_release -m "Release of Model v1.0.0" a1b2c3d. Then, you can simply run git checkout v1.0.0_model_release followed by dvc checkout.

6. Automate with DVC Pipelines

For more complex machine learning workflows, DVC pipelines provide a way to define and track the entire sequence of steps, from data preprocessing to model training and evaluation. A DVC pipeline explicitly defines dependencies between data, code, and models, making your experiments fully reproducible.

You define pipeline stages in a dvc.yaml file. Each stage specifies its commands, inputs (dependencies), and outputs. For example, a simple pipeline might have stages for data preparation and model training:

# dvc.yaml
stages: prepare: cmd: python src/prepare_data.py, input data/raw_data.csv, output data/processed_data.csv deps:
  • src/prepare_data.py
  • data/raw_data.csv
outs:
  • data/processed_data.csv
train: cmd: python src/train_model.py, data data/processed_data.csv, model models/my_model.pkl deps:
  • src/train_model.py
  • data/processed_data.csv
outs:
  • models/my_model.pkl

To run this pipeline, you use dvc repro:

dvc repro

DVC will execute the stages, track their inputs and outputs, and store corresponding metadata in dvc.lock. If you change src/prepare_data.py or data/raw_data.csv, DVC knows that the prepare stage (and consequently the train stage) needs to be rerun. After running dvc repro, you commit the updated dvc.lock file and any new .dvc files (e.g., for models/my_model.pkl) to Git, then dvc push the actual data and model files.

This approach ensures that every time someone checks out a specific Git commit and runs dvc repro, they get the exact same processed data and trained model, assuming the environment is consistent. This eliminates “it worked on my machine” scenarios, a common headache in ML development. The level of transparency and reproducibility offered by DVC pipelines is unparalleled for complex ML projects. It’s what separates ad-hoc scripting from professional ML engineering.

Common Mistake: Not committing the dvc.lock file to Git. The dvc.lock file is important because it records the exact hashes of all tracked files and the full pipeline state. Without it, DVC cannot guarantee reproducibility when collaborators pull your changes or when you try to reproduce a pipeline on a different machine.

Implementing a strong AI model versioning strategy with Git and DVC transforms chaotic machine learning development into an organized, reproducible, and collaborative process. By carefully tracking code, data, and models, teams can confidently iterate, experiment, and deploy, knowing they can always revert to any past state. This disciplined approach is essential for maintaining model integrity and accelerating development cycles in 2026. This also helps in establishing AI fairness metrics by ensuring transparent data and model lineage. Plus, effective versioning can mitigate AI security risks by allowing quick rollbacks to secure states. Finally, this systematic approach supports the broader goals of Agentic AI deployment by providing a stable and auditable foundation.

Why can’t I just store large model files directly in Git?

Storing large model files directly in Git leads to repository bloat, making cloning and pulling operations extremely slow. Git is optimized for small text files and struggles with large binaries, especially when they change frequently. DVC solves this by storing large files in external storage and only committing lightweight pointer files to Git.

What is the difference between Git and DVC?

Git is a version control system primarily designed for tracking changes in source code (text files). DVC (Data Version Control) is an open-source tool built on top of Git, extending its capabilities to handle large files, datasets, and machine learning models. Git manages the code and DVC metadata, while DVC manages the actual large data and model artifacts, linking them to Git commits.

Can DVC track changes to my data even if I don’t use Git?

While DVC can technically track files without a Git repository, its core design and most powerful features are built around smooth integration with Git. DVC relies on Git commits to provide context and history for its tracked data and models. Using DVC without Git significantly diminishes its versioning and reproducibility benefits.

How does DVC handle data deduplication?

DVC uses content-addressable storage, meaning it stores files based on a hash of their content. If you have multiple versions of a file that are identical, or if different files have the same content, DVC only stores one copy in its cache. This prevents redundant storage of identical data, saving space and improving efficiency.

What if I want to share my DVC-versioned project with others?

To share your DVC-versioned project, you share the Git repository as usual. Collaborators clone the Git repository, which includes the .dvc files and the .dvc/config with remote storage details. After cloning, they run dvc pull to download the large data and model files from the configured remote storage to their local DVC cache.

Claudia Mitchell

Lead AI Architect Ph.D., Computer Science, Carnegie Mellon University

Claudia Mitchell is a Lead AI Architect at Quantum Innovations, with 14 years of experience specializing in explainable AI (XAI) for critical decision-making systems. His work focuses on developing transparent and auditable machine learning models across various sectors. Previously, he led the advanced analytics division at Synapse Tech Solutions, where he pioneered a novel framework for bias detection in large language models. Claudia is a widely recognized expert, frequently contributing to industry journals and co-authoring the influential book, 'The Explainable AI Imperative'