fitlog 中文文档¶
fitlog是一款集成了自动版本管理和自动日志记录两种功能的 Python 包,由复旦大学计算机科学技术学院 自然语言处理与深度学习组 的 fastNLP 团队开发的。它可以帮助你在进行实验时方便地保存当前的代码、参数和结果。
提示
如果你是从 readthedocs 访问的该文档,请跳转到我们的 最新网站


用户手册¶
用户手册¶
安装指南¶
fitlog 依赖以下几个包:
docopt>=0.6.2
flask>=1.0.2
numpy>=1.16.4
但您仍然可以使用如下命令一次性完成安装
pip install fitlog
您也可以从 github 中安装 fitlog 的最新稳定版
pip install git+https://github.com/fastnlp/fitlog.git
或者从 gitee 安装 fitlog 的最新稳定版或正在开发的版本
# 最新的稳定版
pip install git+https://gitee.com/fastnlp/fitlog.git
# 正在开发的版本
pip install git+https://gitee.com/fastnlp/fitlog.Git@dev
快速上手¶
Step1¶
我们先使用 命令行工具 命令行初始化项目
>>> fitlog init example
Initialized empty Git repository in /Users/fdujyn/workspaces/example/.git/
[master (root-commit) 0b94c29] Project initialized.
4 files changed, 72 insertions(+)
create mode 100755 .fitconfig
create mode 100755 .gitignore
create mode 100644 logs/default.cfg
create mode 100755 main.py
Initialized empty Git repository in /Users/fdujyn/workspaces/example/.git/
Fitlog project example is initialized.
进入项目文件夹后,我们可以看到文件夹下已经初创建了若干文件夹。其中,以`.`开头的文件和文件夹是fitlog所需的配置文件, 我们一般情况下不需要修改他们;logs 文件夹是 fitlog 默认存放日志的文件夹;main.py 是训练程序的入口文件。
>>> cd example
>>> ls -al
total 24
drwxr-xr-x 8 fdujyn staff 256 Apr 25 19:38 .
drwxr-xr-x@ 20 fdujyn staff 640 Apr 25 19:38 ..
-rwxr-xr-x 1 fdujyn staff 142 Apr 25 19:38 .fitconfig
drwxr-xr-x 14 fdujyn staff 448 Apr 25 19:38 .fitlog
drwxr-xr-x 10 fdujyn staff 320 Apr 25 19:40 .git
-rw-r--r-- 1 fdujyn staff 37 Apr 25 19:38 .gitignore
drwxr-xr-x 3 fdujyn staff 96 Apr 25 19:38 logs
-rwxr-xr-x 1 fdujyn staff 390 Apr 25 19:38 main.py
Step2¶
我们简单地将 main.py 修改为一个类似训练过程的代码,loss 和 acc 是随机生成的。我们把随机种子 rand_seed 看做超参数, 如果rand_seed确定,那么loss 和 acc 关于 step 的函数就是确定的。我们可以选择几组不同的 rand_seed 进行调参,寻找较好的 acc。 fitlog 的其它函数用法参见 用户 API
import fitlog
import random
import argparse
# 从命令行传入参数
parser = argparse.ArgumentParser()
parser.add_argument('--demo', type=int, default=2)
# fitlog.commit(__file__) # 自动 commit 你的代码
fitlog.set_log_dir("logs/") # 设定日志存储的目录
args = parser.parse_args()
fitlog.add_hyper(args) # 通过这种方式记录ArgumentParser的参数
fitlog.add_hyper_in_file(__file__) # 记录本文件中写死的超参数
######hyper
rand_seed = 124
######hyper
random.seed(rand_seed)
best_acc, best_step, step = 0, 0, 0
for i in range(200):
step += 1
if step % 20 == 0:
loss = random.random()
acc = random.random()
fitlog.add_loss(loss,name="Loss",step=step)
fitlog.add_metric({"dev":{"Acc":acc}}, step=step)
if acc>best_acc:
best_acc = acc
fitlog.add_best_metric({"dev":{"Acc":best_acc}})
# 当dev取得更好的performance就在test上evaluate一下
test_acc = random.random()
fitlog.add_best_metric({"test":{"Acc":test_acc}})
fitlog.finish() # finish the logging
我们 rand_seed 分别设为 12, 123, 1234, 12345 进行四次实验,然后就是打开网页服务查看实验结果了。
Step3¶
我们在项目目录下使用命令行工具开启 fitlog 网页服务:
>>> pwd
/Users/fdujyn/workspaces/example
>>> fitlog log logs
Start preparing data.
Finish preparing data. Found 4 records in /Users/fdujyn/workspaces/example/logs.
* Serving Flask app "fitlog.fastserver.app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
如下图所示,我们可以看到这四次实验的记录,其中 fit_id 是 fitlog 帮你自动 commit 的 id,后面几列是实验的超参数和实验的最优结果。

我们可以点开最后一列的图标符号看到 loss 和 acc 的详细变化图:

fitlog 网页服务的详细用法参见 网页服务
命令行工具¶
fitlog 安装后会在系统的命令行中添加fitlog 命令,我们可以使用该命令初始化项目、启动日志网页等等。 fitlog 命令主要有init(初始化项目)、list(查看已有记录)、revert(版本回退)和log(启动日志网页)四种功能,需要用不同的参数进行启动。
Usage:
fitlog <command> [<args>...]
fitlog help <command>
fitlog -h | --help
fitlog --version
Supported commands
init Initialize a fitlog project
list List committed versions
revert Revert to a specific version
log Visualize logs by a server
See "fitlog help <command>" for more information on a specific command
fitlog init¶
fitlog init 可以指定项目名称 <name>
,或者默认把当前文件夹变成 fitlog 项目。它同时给了--hide选项来隐藏.fitconfig 文件;
还有--no-git选项,表示在创建 fitlog 时不创建常规的 git。
Usage:
fitlog init [<name>] [--hide] [--with-git]
fitlog -h | --help
Arguments:
name Name of the fitlog project
Options:
-h --help This is a command to initialize a fitlog project
--hide Hide .fitconfig inside .fitlog folder
--with-git Initialize fitlog with a standard git
Examples:
fitlog init project Create a your project named project
fitlog init Init the current directory with fitlog
注解
假设你在命令行中的 /workspace 目录下使用 fitlog init project --with-git
命令,那么屏幕上会显示如下的内容:
Initialized empty Git repository in /workspace/project/.git/
Auto commit by fitlog
Initialized empty Git repository in /workspace/project/.git/
Fitlog project project is initialized.
前两行表示 fitlog 生成了一个 git 仓库,并将其转化成了隐藏的 fitlog 仓库。第三行表示 fitlog 又帮你生成了
一个明面上的 git 仓库,如果你只想使用 fitlog 而不想手动进行 git 管理,可以去掉 --with-git
参数。
在新版的 fitlog 中,第一行和第三行的提示会被隐藏。
项目初始化后 project 目录下就会有 .git 、 .fitlog 、 logs 三个文件夹,和 .gitignore , .fitconfig 、 main.py 三个文件。
.git 和 .fitlog 都是用于版本控制的文件夹,你不需要详细了解; .gitignore 里记录了不会被 commit 的文件和文件夹, 为了防止 fitlog 和 git 互相管理、产生混乱,里面已有的内容请不要删除; main.py 是使用 fitlog 的一个样例,您可以对它进行删除、改名,只要运行的代码中使用了 fitlog 即可。
.fitconfig 是 fitlog 的配置文件,具体的选项参见 配置文件 。您可以在生成项目时使用 --hide
参数,
让它生成在 .fitlog 文件夹内。logs 文件夹是 fitlog 记录的实验日志的默认目录,
您可以通过修改 .fitconfig 中的选项来改变记录的实验日志的目录,修改后可以删除 logs 文件夹。
fitlog list & revert¶
你可以使用 fitlog list 查看自动存储的版本,并使用 fitlog revert 来进行版本回退,但我们更希望你使用 fitlog 提供的 网页服务 来完成这项任务。
Usage:
fitlog list [<num>] [--show-now]
fitlog revert <fit_id> [<path>] [--id-suffix]
Arguments:
num The number of recent commits you want to list
fit_id The id of the commit you want to revert
path The path to revert the old commit version
Options:
--show-now Show the current version
--id-suffix Use commit id as the suffix of reverted folder
注解
假设你在命令行中的 /workspace/project 目录下,使用 fitlog list 2 --show-now
命令,看到了最近两次自动 commit 的记录,
并知道了当前版本为 fc0af5 。其中 --show-now
显示当前版本。
date&time 2020-05-01 18:06:55
commit_id ab762510af8046f1e913c854d84171ba5b8f8d9a
arguments Run main.py
date&time 2020-05-01 18:10:05
commit_id fc0af540e41e13b22e24f59959a43a434b525db6
arguments Run main.py
Head is fc0af540e41e13b22e24f59959a43a434b525db6
假设你想回退到上个版本 ab7625 。使用 fitlog revert ab7625
命令, 一个 ab7625 版本的项目就会出现在
/workspace/project_revert 的位置。您可以通过指定 <path>
的方式改变回退目录(例如:指定为 /workspace/project_v1),
也可以使用 --id-suffix
参数使回退目录含有版本号后缀,变为 /workspace/project_revert_ab7625 。
警告
注意!使用版本回退功能 一定 会覆盖目标文件夹(如 /workspace/project_revert )中的文件,请不要直接在 project_revert 目录下工作。
fitlog log¶
你可以使用 fitlog log 命令来启动一个管理日志的网页,你必须提供参数 <log-dir>
来表示日志存放的位置,项目初始化时会生成符合条件的 logs 文件夹。
你还可以指定配置文件的名称、网页对应的端口号和服务器停止的时间。
Usage:
fitlog log <log-dir> [--log-config-name=L] [--port=P] [--standby-hours=S] [--token=T] [--ip=I]
Arguments:
log-dir Where to find logs.
Options:
-h --help This is a command to start fitlog server to visualize logs.
-l=L --log-config-name Log server config name. Must under the folder of <log-dir>. [default: default.cfg]
-p=P --port Which port to start to looking for usable port.[default: 5000]
-s=S --standby-hours How long to wait before the server . [default: 48]
-t=T --token If this is used, your have to specify the token when accessing. Default no token.
-i=I --ip Which ip to bind to. Default is 0.0.0.0 [default: 0.0.0.0]
环境变量¶
在新版的 fitlog 中,用户可以在运行程序前使用环境变量 FITLOG_FLAG
影响 fitlog 的作用。
注意,该环境变量发生作用的时刻在于 fitlog 被 import 的瞬间,之后再改变环境变量不影响 fitlog 的作用。
环境变量 FITLOG_FLAG
有三种值: DEBUG
, NO_COMMIT
和其它(包括为空)。
当 FITLOG_FLAG=DEBUG
时,程序中对 fitlog 的所有调用都不起作用。你也可以在代码中使用 fitlog.debug()
产生类似的效果。
当 FITLOG_FLAG=NO_COMMIT
时,程序中使用 fitlog 记录数据的调用正常,但 fitlog.commit()
失效。你可以在同时运行多个实验时,只进行一次自动 commit。
当 FITLOG_FLAG
为空或等于其它值时,不产生额外的效果。
网页服务¶
一般情况下可以通过自行尝试掌握 fitlog 网页的用法,你也可以从实验室内部的讲座中获取详细的使用方法。
配置文件¶
fitlog 的配置文件有 .fitconfig
.fitconfig¶
.fitconfig 文件是 fitlog 的配置文件,一般位于 fitlog 项目的根目录下,也可以放置在项目的根目录中的 .fitlog 文件夹内。 .fitconfig 中的默认内容如下:
[fit_settings]
watched_rules = *.py
watched_rules
配置的是 fitlog 会自动进行 commit 的文件的规则,等号后面是一系列用英文逗号 ,
隔开的规则,
这些规则会被写到 .fitlog/.gitignore 中,用于选取需要被 commit 的文件。
你可以添加适当的空格来让配置项更加可读,例如: watched_rules = *.py, *.mat, test_*.bak 。
default.cfg¶
default.cfg 是日志文件夹(默认为项目根目录下的 logs 文件夹)中的配置文件。您可以复制或改名这个文件, 只要在命令行启动网页服务时指定配置文件即可。各个选项的功能请参考文件中的注释。
[frontend_settings]
# 以下的几个设置主要是用于控制前端的显示
Ignore_null_value_when_filter=True
Wrap_display=False
Pagination=True
Hide_hidden_columns_when_reorder=False
# 前端的任何变动都不会尝试更新到服务器,即所有改动不会保存
Offline=False
# 是否保存本次前端页面的改动(包括删除,增加,column排序等)。在server关闭时和更改config时会判断
Save_settings=True
# row是否是可以通过拖拽交换的,如果可以交换则无法进行复制
Reorderable_rows=False
# 当选择revert代码时 revert到的路径: ../<pj_name>-revert 或 ../<pj_name>-revert-<fit_id>
No_suffix_when_reset=True
# 是否忽略掉filter_condition中的不存在对应key的log
Ignore_filter_condition_not_exist_log=True
[basic_settings]
# 如果有内容长度超过这个值,在前端就会被用...替代。
str_max_length=20
# float的值保留几位小数
round_to=6
# 是否在表格中忽略不改变的column
ignore_unchanged_columns=True
[data_settings]
# 在这里的log将不在前端显示出来,但是可以通过display点击出来。建议通过前端选择
hidden_logs=
# 在这里的log将在前端删除。建议通过前端选择
deleted_logs=
# 可以设置条件,只有满足以下条件的field才会被显示,请通过前端增加filter条件。
filter_condition=
[column_settings]
# 隐藏的column,建议通过前端选择
hidden_columns=
# 不需要显示的column,用逗号隔开,不要使用引号。需要将其从父节点一直写到它本身,比如排除meta中的fit_id, 写为meta-fit_id
exclude_columns=
# 允许编辑的column
editable_columns=memo,meta-fit_msg,meta-git_msg
# column的显示顺序,强烈推荐不要手动更改
column_order=
[chart_settings]
# 在走势图中,每个对象最多显示的点的数量,不要太大,否则前端可能会卡住
max_points=200
# 不需要在走势图中显示的column名称
chart_exclude_columns=
# 前端间隔秒多久尝试更新一次走势图,不要设置为太小。
update_every=4
# 如果前端超过max_no_updates次更新都没有获取到更新的数据,就停止刷新。如果evaluation的时间特别长,可能需要调大这个选项。
max_no_updates=40
常见问题¶
1.如果在debug阶段,不希望fitlog发生任何作用,那么直接在入口代码处加入fitlog.debug() 就可以让所有的fitlog调用不起任何作用,debug结束再注释掉这一行就可以了。
2.fitlog 默认只有在产生了第一个metric或loss的时候才会创建log文件夹,防止因为其它bug还没运行 到model就崩溃产生大量无意义的log。
3.如果使用了分布式训练,一般只需要主进程记录fitlog就好。这个时候可以通过将非主进程的fitlog设置fitlog.debug()
import torch
import fitlog
if torch.distributed.get_rank()>0:
fitlog.debug()
4.不要通过多进程使用fitlog,即multiprocessing模块。
5.fitlog.commit()只需要在某个python文件调用就可以了,一般就在入口python文件即可。
6.传入到fitlog的各种参数、metric的名称,请 避免特殊符号(例如$%!#@空格),请只使用_与各种字母的组合 , 因为特殊符号可能导致网页端显示不正常。
开发参考¶
开发参考¶
以下 API 文档用于帮助开发者理解 fitlog 的架构:
fitlog.fastlog package¶
fastlog 是 fitlog 的一部分,用于帮助用户进行日志管理。fastlog 默认使用工作目录下的 logs 文件做为存储和配置路径。 默认配置文件为default.cfg。用户可以使用 fitlog 命令行工具初始化项目,启动服务器,并在网页上查看日志。
fitlog.fastlog.log_read module¶
-
class
fitlog.fastlog.log_read.
LogReader
[源代码]¶ 基类:
object
用于读取日志的类, 用于配合Table使用
-
fitlog.fastlog.log_read.
is_log_dir_has_step
(_save_log_dir: str, check_files='metric.log', 'loss.log') → bool[源代码]¶ 给定log_dir, 判断是否有step数据
:param _save_log_dir 日志存放的目录 :param check_files: 检查file是否含有step :return: 是否有step数据
-
fitlog.fastlog.log_read.
merge
(a: dict, b: dict, use_b: bool = True) → dict[源代码]¶ 将两个dict recursive合并到a中,有相同key的,根据use_b判断使用哪个值
- 参数
a -- 字典 a
b -- 字典 b
use_b -- 是否使用字典 b 的值
- 返回
返回字典 a
-
fitlog.fastlog.log_read.
is_dirname_log_record
(dir_path: str) → bool[源代码]¶ 检查dir_path是否是一个合法的log目录。合法的log目录里必须包含meta.log。
- 参数
dir_path -- 被检测的路径
- 返回
是否合法
-
fitlog.fastlog.log_read.
is_log_record_finish
(save_log_dir: str) → bool[源代码]¶ 检测日志的记录是否已经结束
- 参数
save_log_dir -- 日志存放的目录
- 返回
-
class
fitlog.fastlog.log_read.
StandbyStepLogReader
(save_log_dir: str, uuid: str, wait_seconds: int = 60, max_no_updates: int = 30)[源代码]¶ 基类:
threading.Thread
用于多线程读取日志的类. 配合画图使用的。
- 参数
save_log_dir -- 日志存放的目录
uuid -- 用于唯一识别 Reader 的 uuid
wait_seconds -- 在文件关闭后再等待{wait_seconds}秒结束进程
max_no_updates -- 在{max_no_updates}次都没有更新时结束进程
-
static
read_update_single_log
(filepaths: List[str], ranges: dict) → dict[源代码]¶ 调用这个函数,获取filepaths中满足range_min, range_max的log
- 参数
filepaths -- 完整的path路径
ranges -- {'metric':[min, max] }
- 返回
返回值的结构如下。loss这个list是进行了step排序的
{ loss: [dict('step':x, epoch:value, 'loss':{'loss1':xx})], metric:[dict('step':x, epoch:value, 'metric':{'SpanFMetric':{'f':xx}})] }
-
read_update
(only_once: bool = False, handler_names='metric', 'loss') → dict[源代码]¶ 调用这个函数,获取新的更新。如果第一次调用则是读取到当前所有的记录。
- 参数
only_once -- 是否只读取内容一次。是的话就不会保持读取到的行数,之后直接退出了
handler_names -- 只check包含在handler_name的内容
- 返回
返回值的结构如下
{ loss: [dict('step':x, epoch:value, 'loss':{}), ...], # 或[dict('step':x, epoch:value, 'loss':value), ...] metric:[dict('step':x, epoch:value, 'metric':{'SpanFMetric':xxx})], finish:bool(not every time), total_steps:int(only the first access) }
fitlog.fastlog.logger module¶
-
class
fitlog.fastlog.logger.
FitlogConfig
(**kwargs)[源代码]¶ 基类:
object
用于add_hyper函数的基类。 继承后无需实例化直接传入add_hyper。
-
class
fitlog.fastlog.logger.
Logger
[源代码]¶ 基类:
object
用于处理日志的类,fitlog 的核心
-
set_rng_seed
(rng_seed: int = None, random: bool = True, numpy: bool = True, pytorch: bool = True, deterministic: bool = True)[源代码]¶ - 设置模块的随机数种子。由于pytorch还存在cudnn导致的非deterministic的运行,所以一些情况下可能即使seed一样,结果也不一致
需要在fitlog.commit()或fitlog.set_log_dir()之后运行才会记录该rng_seed到log中
- 参数
rng_seed (int) -- 将这些模块的随机数设置到多少,默认为随机生成一个。
random (bool,) -- 是否将python自带的random模块的seed设置为rng_seed.
numpy (bool,) -- 是否将numpy的seed设置为rng_seed.
pytorch (bool,) -- 是否将pytorch的seed设置为rng_seed(设置torch.manual_seed和torch.cuda.manual_seed_all).
deterministic (bool,) -- 是否将pytorch的torch.backends.cudnn.deterministic设置为True
-
fitlog.fastgit package¶
fastgit(简称 fit) 是 fitlog 的一部分,用于帮助用户进行自动 commit。自动 commit 的文件在 .fitlog 文件夹中,与 .git 文件夹类似。 用户需要使用 fitlog 命令行工具初始化项目,项目默认会生成一个名为 .fitconfig 的配置文件,可以配置监控文件的规则等参数。
fitlog.fastgit.committer module¶
-
class
fitlog.fastgit.committer.
Commit
(commit_id: str, msg: str)[源代码]¶ 基类:
list
Commit 是一个有两个元素的 list,第一个元素是commit-id,第二个元素是commit-message
- 参数
commit_id -- 本次 commit 的 commit-id
msg -- 本次 commit 的 commit-message
- 返回
-
class
fitlog.fastgit.committer.
Info
(status: int, msg: Union[str, fitlog.fastgit.committer.Commit, List[str], List[fitlog.fastgit.committer.Commit]])[源代码]¶ 基类:
dict
Info 是一个dict,有 status 和 msg 两个字段, 用于给返回信息加上状态码
- 参数
status -- 状态码,0表示没有错误
msg -- 返回信息
- 返回
-
class
fitlog.fastgit.committer.
Committer
[源代码]¶ 基类:
object
用于自动 commit 的类,fastgit子模块使用此类实现单例模式。实例化后的对象会记录工作目录,配置文件路径等信息。 对外只暴露有用的接口,内部处理函数的文档请在代码中查看。
-
commit
(file: str, commit_message: str = None) → fitlog.fastgit.committer.Info[源代码]¶ 用户用该方法进行 commit
- 参数
file -- 执行文件路径,期望传入用户程序中的 __file__
commit_message -- 自动 commit 的 commit-message
- 返回
返回带状态码的信息。如果成功,信息为 commit-id
-
get_config
(run_file_path: str = None) → fitlog.fastgit.committer.Info[源代码]¶ 通过执行文件的路径获取配置信息
- 参数
run_file_path -- 执行文件的路径
- 返回
返回带状态码的信息。如果成功,信息为工作目录的路径
-
fitlog_last_commit
() → fitlog.fastgit.committer.Commit[源代码]¶ 返回 self.last_commit 中记录的上一次的commit
- 返回
Commit是一个元组,第一个参数为 commit-id,第二个参数为 commit-message
-
fitlog_commits
() → List[fitlog.fastgit.committer.Commit][源代码]¶ 返回 self.commits 中记录的所有的commit
- 返回
返回一个 Commit 类型的数组
-
static
git_last_commit_info
(work_dir: str) → fitlog.fastgit.committer.Info[源代码]¶ 获取 work_dir 或其祖其先目录上标准 git 的上一次 commit 的信息
- 参数
work_dir -- 工作目录的路径
- 返回
返回带状态码的信息。如果成功,信息为一个 Commit 类型的 commit 信息
-
static
fit_last_commit_info
(work_dir: str) → fitlog.fastgit.committer.Info[源代码]¶ 获取 work_dir 或其祖其先目录上 fitlog 的上一次 commit 信息
- 参数
work_dir -- 工作目录的路径
- 返回
返回带状态码的信息。如果成功,信息为一个 Commit 类型的 commit 信息
-
revert_to_directory
(commit_id: str, path: str, id_suffix: bool)[源代码]¶ 命令行用来回退 fastgit 的一个目标版本到指定放置路径
- 参数
commit_id -- 回退版本的 commit-id
path -- 回退版本的指定放置路径
id_suffix -- 回退版本的放置文件夹是否包含 commit-id 做为后缀
- 返回
-
init_project
(pj_name: str, version: str = 'normal', hide: bool = False, git: bool = True) → int[源代码]¶ 命令行用来初始化一个 fitlog 项目
- 参数
pj_name -- 项目名称
version -- 项目初始化文件夹的版本,目前只有 normal 这一种
hide -- 是否隐藏 .fitconfig 文件到 .fitlog 文件夹中
git -- 是否在初始化 fitlog 的同时为项目初始化 git
- 返回
状态码。0表示正常完成,其它错误码与系统相关
-
short_logs
(show_now: bool = False, last_num: int = None)[源代码]¶ 在命令行用来查看 fastgit 的自带 logs
- 参数
show_now -- 是否显示当前版本在 logs 中的位置
last_num -- 显示最近的 {last_num} 条记录
- 返回
-
fitlog_revert
(commit_id: str, run_file_path: str = None, id_suffix: bool = False) → fitlog.fastgit.committer.Info[源代码]¶ fitlog 调用此接口进行版本回退
- 参数
commit_id -- 需要回退版本的 commit-id
run_file_path -- 执行文件的路径
id_suffix -- 回退版本的放置文件夹是否包含 commit-id 做为后缀
- 返回
返回带状态码的信息。如果成功,信息为回退版本的放置路径
-