Git LFS(Large File Storage),表示 Git 大文件存储。一直以来 git 只能提交存储小文件大远程仓库,当遇到大文件时 push 会遇到卡死等问题。因此,出现了 Git LFS,解决 git 仓库的大文件的版本管理。随着深度学习模型越来越大,特别是大模型、多模态大模型的出现,预训练得到的权重文件多达几十G不等,这些大文件的管理使用 LFS 再合适不过了。如 Hugging Face 上的模型仓库大文件都是用 LFS 管理。本篇介绍如何使用 Git LFS.

Git LFS 是一个命令行扩展和规范,用于使用 Git 管理大文件。 该客户端是用 Go 编写的,预编译的二进制文件可用于 Mac、Windows、Linux 和 FreeBSD。

安装

官网安装地址:https://github.com/git-lfs/git-lfs/tree/main#installing

Note: Git LFS requires at least Git 1.8.2 on Linux or 1.8.5 on macOS.

1
2
3
4
5
6
7
8
9
10
11
12
# Debian/Ubuntu
# 添加仓库
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
# 安装
sudo apt-get install git-lfs

# Redhat/CentOS
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.rpm.sh | sudo bash
sudo yum install git-lfs

# Mac
brew install git-lfs

安装完成后,使用如下命令配置 lfs:

1
git lfs install

如果出现 Git LFS initialized,那么说明配置成功。注意,当运行该命令时当前目录不是一个 git 仓库时,会有一些警告信息,可不用管。

使用

为仓库新添加大文件

当原来仓库不是使用 LFS 管理时,为新仓库增加了一个大文件,如 “a.mp4”,那么可以如下操作,提交到远程仓库中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 设置跟踪该文件
git lfs track a.mp4
# or 跟踪所有MP4视频文件
git lfs track "*.mp4"

# 此时会自动创建一个 .gitattributes 配置文件,我们需要把它提交到远程仓库
git add .gitattributes
git commit -m "track *.mp4 files using Git LFS"

# 如果还有其他的一些普通小文件添加,可以按原方法添加
git add small.txt
git commit -m "add env config"

# 查看LFS文件
git lfs ls-files

# 提交到远程仓库
git push origin main

此时,在远程仓库如 GitHub/Gitlab 上就能看到文件后面有一个 LFS 标志。

克隆别人的仓库(如果有LFS大文件)时,可以使用如下方法:

1
2
3
4
5
6
# 如果第一次安装 git-lfs,那么需要配置
# 如果之前配置过,可以直接跳过该步骤,想正常的克隆一样
git lfs install

# 克隆
git clone https://huggingface.co/bert-base-chinese

把现有仓库中某个文件改为LFS

有时候,我们想把仓库中本来已经存在的大文件用LFS管理,但是,已经提交到远程仓库了。我们可以如下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 先从远程仓库获取最新
git pull

# 修改某个文件用LFS管理,--everything 表示同时把所有分支更改
git lfs migrate import --include="*.mp4" --everything
# 指定分支更改
git lfs migrate import --include-ref=main --include="*.mp4"

# 提交本地更改到远程仓库,必须使用 --force
# 对于 gitlab,默认仓库设置是关闭 --force,因此需要打开:"Settings" -> "Repository" -> "Protected branches"
# gitlab 中 LFS 大文件的存储路径是 /etc/gitlab/gitlab.rb 里面的 gitlab_rails['lfs_storage_path'] = "/var/opt/gitlab/gitlab-rails/shared/lfs-objects"
git push --all --force

# 如果切换为LFS后,发现本地仓库的 .git 变得很大,这是因为之前的提交还在,因此需要使用下面方法清理
git reflog expire --expire-unreachable=now --all
git gc --prune=now

# 如果想撤回添加到LFS的大文件,可以使用如下方法
git lfs migrate export --include="*.mp4" --everything

QA

  1. 当本地 git 未安装 git-lfs 时,克隆远程有LFS管理的代码仓库时,不会把LFS管理的大文件的源文件下载下来,下载下来的是链接文件,打开内容如下:
    1
    2
    3
    version https://git-lfs.github.com/spec/v1
    oid sha256:189d0cea7ee085a79716ebf5e6bf29cd0d8aece08c0b0f25cbf15b3aa74d09cf
    size 17190
  2. 当本地已经配置了 Git LFS,但是不想下载大文件时,可以使用如下方法:
    1
    2
    3
    # if you want to clone without large files – just their pointers
    # prepend your git clone with the following env var:
    GIT_LFS_SKIP_SMUDGE=1
  3. 使用 GIT LFS 帮助
    1
    git lfs help <subcommand>
  4. 查看 GIT LFS 环境变量
    1
    git lfs env

参考文献

  1. git-lfs
  2. Git LFS简介
  3. Git-LFS 使用和迁移
  4. 极狐GitLab Git 大文件存储 (LFS) 管理
  5. 解决 GitLab: You are not allowed to force push code to a protected branch on this project问题
  6. Git LFS Tutorial
  7. LFS 迁移指南