愿得一心人,白首不相离

——《白头吟》汉/卓文君

解释

Submodule 是一个多项目管理工具,它允许将子项目以独立的 git 项目添加到主项目,而主项目以 submodule 的形式拥有子项目。子项目拥有自己的 commit、push、pull,而与主项目互不干扰。主项目只需要记录子项目的地址和所需要的 commit id,通过地址和 commit id 就能够得到对应的子项目。

[常用情景] 在我们的项目中调用轮子且希望两者解藕,可以分别进行版本管理。

添加

1
2
3
4
5
/*
url: 子项目远程地址或本地地址
path: 子项目路径,可省略
*/
git submodule add [url] [path]

可以看到多了文件: .gitmodules,.gitmodules 储存了 submodule 的路径及远程地址。对改变进行提交。

1
2
git add
git commit -m "xxx"

克隆

在clone带有submodules的项目时,正常clone主项目地址不会拉取submodules,可以使用如下命令同时clone主项目和依赖模块:

1
git clone --recurse-submodules [url]

更新

因为我们的目的是解藕主项目对依赖项目的关联,我在主项目中设置git不跟踪submodules,此时对submodules的更新不会提交到依赖项目中。

在使用中发现依赖项目中存在错误时,切换进submodules自己独立的仓库进行修改和PR,非 submodule 的开发人员就不用关心 submodule 是否更新。

删除

1
2
3
4
5
6
7
8
9
10
11
12
13
# 逆初始化模块,submodule为子模块目录,执行后可发现子模块目录被清空
git submodule deinit [submodule_name]

# 执行如下命令还能看到子项目信息
git submodule

# 删除.gitmodules中记录的模块信息(--cached选项清除.git/modules中的缓存)
git rm --cached test2sub
# 执行如下命令已看看不到删除的子项目信息了
git submodule

# 提交修改
git commit -m "xxx"

P.S.

  • 使用GitHub Action进行自动部署的时候需要对submodules进行额外的配置
  • ↑所以我一般将更新频率慢(固定)的submodules融入自己的项目,以较低代价防止奇奇怪怪的事情发生

Reference

  1. https://gist.github.com/myusuf3/7f645819ded92bda6677

思量。能几许,忧愁风雨,一半相妨。又何须抵死,说短论长。
幸对清风皓月,苔茵展、云幕高张。江南好,千钟美酒,一曲满庭芳。

——《满庭芳》宋/苏轼

GitHub Pages服务对与每一个用户开放username.github.io的域名解析和托管,如果你是普通用户,gh-page服务将仅对公有仓库开放,将仓库转为私有后gh-page停止解析和更新;对于学生Pro和付费Pro及以上等级用户,gh-page服务将同时对公有和私有仓库提供服务,然而Travis CI仅对公有仓库免费使用。

综上,本文面向于想使用GitHub Pages服务应用于私有仓库的大家伙。

P.S. 把托管gh-page的仓库私有化可以减少隐私泄露。但,所有(部署分支的)文件仍然可以被爬取/扫描。

前言

之前一直用最简洁直白的GitHub Pages+Jekyll进行部落格的书写(反正没有关注度不是嘛)。

近期因为疾控问题在家思思发抖,但学习和工作不能停,就干些一直以来没时间做/没接触的事情。

  • 把gh-pages仓库私有
  • 使用Hexo替代Jekyll
  • 使用Github Action实现自动部署

使用ssh-keygen生成秘钥对实现部署

1
2
3
4
5
# set up private key for deploy
mkdir -p ~/.ssh/
echo "$ACTION_DEPLOY_KEY" | tr -d '\r' > ~/.ssh/id_rsa # 配置秘钥
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts

使用github personal access token实现部署

类似于 Google 两步验证中的备用验证码,不过google token是单次生成(可见/查询)使用后销毁,github personal token是单次生成销毁(不可见)多次使用。

依次进入 Settings >> Developer settings >> Personal access tokens,点击 Generate new token

部署部落格仅需要对repo的读写权限。此页面关闭之后 token 将不可见(快记下来!!)。

设置仓库

因为gh-pages服务默认部署的分支是master,所以有如下两种常见的仓库设置方法:

  • 双仓库:仓库A用于存储hexo源文件,仓库B(xxx.github.io)用于hexo生成文件的部署,push A触发GitHub Action更新部署仓库B
  • 单仓库:source分支用于存储hexo源文件,master分支用于hexo生成文件的部署,push source触发GitHub Action更新master并部署gh-pages

这里我采用的是单仓库双分支的设置,注意不要手贱merge了就好,不然还要花时间(action刷新master之后history会消失)。

上一步生成的 token 我们不能以明文形式存放,所以要设置为仓库的 Secrets,这样就可用 Secrets 隐式引用 token。依次进入(仓库的)setting >> Secrets >> Add a new secret,名称填 GITHUB_ACCESS_TOKEN,内容填刚刚的token。

配置 GitHub Action

修改 Hexo 的 _config.yml,将下面 id 和 仓库名修改为自己的。

1
2
3
4
deploy:
type: git
repo: https://[email protected]/your-github-id/your-github-repo-name.git
branch: master

在 Hexo 根目录下新建 .github/workflows/blogci.yml,内容如下,将 git 的信息修改为自己的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
name: BlogCI

on: [push]

jobs:
build:

runs-on: ubuntu-latest

steps:
- name: Download Source file
uses: actions/[email protected]
with:
ref: source # 此处修改为自己存放 Hexo 源文件的分支

- name: Prepare Node env
uses: actions/[email protected]
with:
node-version: "10.x" # 此处和自己的nodejs版本对应(10,12测试成功)

- name: Set Env
env:
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_ACCESS_TOKEN }}
run: |
git config --global user.name 'my_name' # github用户名
git config --global user.email 'my_email' # github邮箱
sed -i "s/GITHUB_ACCESS_TOKEN/$GITHUB_ACCESS_TOKEN/g" ./_config.yml

- name: Hexo
run: |
npm i -g hexo-cli
npm i
hexo clean && hexo g && hexo d

最后也可以采用另一种写法(使用局部安装避免npm安装依赖出错):

1
2
3
4
5
6
- name: Hexo
run: |
npm install hexo
npm install
npx hexo clean
npx hexo g -d

保存后推送到 GitHub,再进入 Actions 会发现 BlogCI 已经在工作。

价格

目前GitHub Action采用免费时长的营销策略:

  • 对于普通用户每个月可以免费使用2000分钟
  • 对于Pro用户每个月免费使用3000分钟

据我统计一般成功的推送action执行时间在40~60s之间,执行时间较长的(3~5min)一般都是出错了 :(

按这个时间进行估算,用户在action上无需额外消费 :)

Reference

  1. gh-pages服务 https://pages.github.com/
  2. Jekyll部落格框架 https://jekyllrb.com/
  3. Google备用验证码 https://support.google.com/accounts/answer/1187538
  4. 参考的Blog 有改进和勘误 https://rook1e.com/p/6.html
  5. Hexo中文文档 https://hexo.io/zh-cn/docs/

Hands on empirically searching for learning rate

3e-4 is the best learning rate for Adam, hands down.

如果 3e-4 在我的数据集上无法作用于模型,我会采取两个办法:

  • 如果看不到损失值移动的明确方向,我会降低学习率。
  • 如果在小数点后 5 或 6 位才能看到损失减少,我会提高学习率。
  • 如有必要,我会再重复上面的过程。

2015 年,Leslie N. Smith 将上述的反复试验法形式化为一种名为 LR Range Test 的技术。这个方法很简单,你只需将模型和数据迭代几次,把学习率初始值设置得比较小,然后在每次迭代后增加。你需要记录学习率的每次损失并将它画出。

LR Range Test 图应该包括三个区域,第一个区域中学习率太小以至于损失几乎没有减少,第二个区域里损失收敛很快,最后一个区域中学习率太大以至于损失开始发散。

除了确保你正在选择最佳学习率之外,该技术还可以作为一种「保险」检查。如果 LR Range Test 没有显示上述 3 个区域,或者图中有断层(损失中有 NaN 值),则表示模型中有缺陷或者数据中有错误。在运行模型之前,最好获取一个理想的 LR range 图。

从童年起,我便独自一人,照顾着历代的星辰。

——《孤独》中/白鹤林

但遇见你以后,念念落地生根,未来欢愉在等。

——佚名补

目录

闲话TPU #1 背景/价格/TFRC计划及羊毛
闲话TPU #2 配置GCP环境/创建TPU实例
闲话TPU #3 模型编写
闲话TPU #4 Coral Edge TPU赋能移动端
闲话TPU #5 那些使用TPU训练的巨型模型(时间和算力需求)

那些使用TPU训练的巨型语言模型

Six/Those Huge Neural Network Models, Training Time and Computing Resources

BERT

原论文中描述,大型 BERT 模型在 16 个 Cloud TPU 上需要训练 4 天:

“Training of BERT_BASE was performed on 4 Cloud TPUs in Pod configuration (16 TPU chips total).13 Training of BERT_LARGE was performed on 16 Cloud TPUs (64 TPU chips total). Each pretraining took 4 days to complete.”

现在我们来算一下成本,16 个 Cloud TPU v3 总训练成本为 16×8×24×4=12288 美元。有研究者在 Reddit 中回复作者,他们可以使用更便宜的抢占式(Preemptible)TPU 训练模型,那样成本约为 16×2.4×24×4=3686.4 美元。不过一般的 TPU 优先于抢占式 TPU,如果它们需要计算资源,可以暂停抢占式对资源的调用。

BERT 的作者在 Reddit 上也表示预训练的计算量非常大,Jacob 说:「OpenAI 的 Transformer 有 12 层、768 个隐藏单元,他们使用 8 块 P100 在 8 亿词量的数据集上训练 40 个 Epoch 需要一个月,而 BERT-Large 模型有 24 层、2014 个隐藏单元,它们在有 33 亿词量的数据集上需要训练 40 个 Epoch,因此在 8 块 P100 上可能需要 1 年?16 个 Cloud TPU 已经是非常大的计算力了。」

为了做对比,这里统一用一般的 TPU 价格计算成本,因此 BERT 训练一次大概需要 1.23 万美元。

GPT-2

今年另一个非常受关注的语言模型就是 GPT-2 了,它充分展示了什么才算大模型。我们可以理解为,GPT-2就是在 GPT 的基础上放大十多倍,它需要的算力应该比 BERT 还大。堆了这么多算力与数据,GPT-2 的效果确实惊人,它根据一个前提就能从容地把故事编下去。

但是在 GPT-2 原论文中,我们没找到关于算力的描述,只找到了疑似论文作者的描述。他表明 GPT-2 用了 64 个 Cloud TPU v3,训练了一周多一点。

如果按这个数据,那么训练成本为 32×8×24×7=43008 美元,这个成本已经是训练 BERT 的 3 到 4 倍了。

XLNet

2018 年,谷歌发布大规模预训练语言模型 BERT ,为 NLP 领域带来了极大的惊喜。但最近,Quoc V. Le 等研究者提出的 XLNet 在 20 个任务上超过了 BERT 的表现,并在 18 个任务上取得了当前最佳效果。既然效果这么好,那么它的成本会不会也超过 BERT?

在原论文中,作者表示 XLNet 大模型在 128 个 Cloud TPU v3 下需要训练 2 天半:

“We train XLNet-Large on 512 TPU v3 chips for 500K steps with an Adam optimizer, linear learning rate decay and a batch size of 2048, which takes about 2.5 days. ”

这样算起来,128×8×24×2.5=61440 美元,没想到 XLNet 训练一次的费用比 GPT-2 还高,达到了 BERT 的 5 倍。既然成本这么高,以后可以考虑用预训练的 XLNet 代替 BERT 了。

在看了 XLNet 的算力成本之后,有开发者感叹:「谢天谢地我不在 NLP 领域工作,要是让我去说服老板训练一个模型花 6 万多美元,而且还不能保证这个模型一定好用,我觉得我会哭……」

BigGAN

视觉模型中,常见高成本任务就是训练高分辨率的 GAN 了。在去年,研究者表示他们训练 512×512 像素的图像需要 64 个 Cloud TPU v3,训练 24 到 48 个小时:

“We train on a Google TPU v3 Pod, with the number of cores proportional to the resolution: 128 for 128×128, 256 for 256×256, and 512 for 512×512. Training takes between 24 and 48 hours for most models.”

如果我们用最大训练时间 48 小时为基准,那么训练成本为 64×8×48=24576 美元。是的,BigGAN 的训练成本也比 BERT 高,大约是它的两倍左右。

StyleGAN

最后,我们统计一下 StyleGAN 的训练成本,因为这篇论文是英伟达提出来的,所以用的是 Tesla V100。该论文使用的 FFHQ 数据集由 1024×1024 的人脸图像组成,模型使用 8 张 Tesla V100 需要训练一星期:

“Our training time is approximately one week on an NVIDIA DGX-1 with 8 Tesla V100 GPUs.”

这里我们按照谷歌云的价格计算总成本,从而更好地做对比。总体而言,训练成本为 8×2.48×24×7=3333.12 美元。可能因为数据集仅限于人脸,StyleGAN 的成本要比 BigGAN 低很多。

Reference

  1. https://www.reddit.com/r/MachineLearning/comments/c2pfgb/d_how_can_you_do_great_ai_research_when_you_dont/
  2. https://www.reddit.com/r/MachineLearning/comments/c59ikz/r_it_costs_245000_to_train_the_xlnet_model512_tpu/
  3. https://www.reddit.com/r/MachineLearning/comments/9nfqxz/r_bert_pretraining_of_deep_bidirectional/