本地部署Qlib量化投研框架:从环境搭建到策略回测的完整指南

1. 为什么要在本地跑一套量化投研框架

第一次接触Qlib是在一个做量化研究的朋友那里。他当时吐槽说,云端环境跑回测,数据上传下载来回折腾,一个因子验证要等半天,网络一断前功尽弃。后来他把整套框架搬到了本地工作站,用SSD存数据、多核跑回测,效率直接翻了几倍。这件事让我意识到,对于做量化投研的人来说,本地部署不是可选项,而是刚需。

Qlib是微软亚洲研究院开源的一个量化投资平台,覆盖了从数据管理、因子挖掘、模型训练到回测评估的完整链路。它内置了多种机器学习模型(LightGBM、LSTM、Transformer等),也支持自定义策略接入。说白了,它把量化研究里那些重复造轮子的活儿——数据清洗、特征工程、滚动训练、绩效归因——都封装成了标准化模块,你只需要关注策略逻辑本身。

但问题在于,官方文档虽然全面,却偏向API说明,对于“从零开始把环境搭起来”这件事,缺少一条清晰的路径。尤其是国内网络环境下,依赖安装、数据下载、路径配置这几个环节,新手很容易卡住。我前后在三个不同环境(Linux服务器、Windows工作站、macOS笔记本)上部署过Qlib,踩了不少坑,也总结了一套相对顺畅的流程。

这篇文章面向的是有一定Python基础、想做量化策略研究、但还没把Qlib跑起来的人。我会从环境准备讲起,一步步带你完成安装、数据初始化、第一个策略回测,最后分享一些实际使用中的调优经验和常见问题的排查思路。全程基于我自己的实操记录,命令和配置都可以直接复制使用。

注意:Qlib的版本迭代较快,本文基于pyqlib 0.9.x系列编写,不同版本间API可能有细微差异,建议以官方仓库的release note为准。

2. 环境准备:Python版本、依赖与目录规划

2.1 Python版本的选择逻辑

Qlib对Python版本有明确要求,官方推荐3.8到3.10。我实测下来,3.9是最稳的。为什么这么说?3.7及以下缺少一些类型注解特性,部分依赖包已经不再维护对应版本;3.11以上虽然语法更新,但Qlib依赖的某些科学计算库(如早期版本的numpy、scipy)在3.11上编译容易出问题,尤其是Windows环境。

如果你用的是conda,创建一个独立环境是最省心的做法:

conda create -n qlib python=3.9 conda activate qlib

用venv也可以,但conda在处理科学计算库的二进制依赖时更省事,特别是在Windows上。我试过在Windows用纯pip装Qlib,numpy的MKL加速库经常装不上,换成conda就自动解决了。

2.2 核心依赖与安装顺序

Qlib的安装本身不复杂,但依赖链比较长。直接pip install pyqlib会一次性拉取所有依赖,但国内网络下速度堪忧。我的建议是先配好镜像源,再分步安装。

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip install pyqlib

如果你需要跑深度学习模型(LSTM、Transformer等),还需要额外安装PyTorch。这里有个坑:PyTorch的版本要和CUDA驱动匹配。如果你没有NVIDIA显卡,直接装CPU版本就行,Qlib的LightGBM模型在CPU上跑回测完全够用。

# CPU版本,适合大多数场景 pip install torch --index-url https://download.pytorch.org/whl/cpu

提示:不要一上来就装GPU版本的PyTorch。我见过不少人为了“以后可能用GPU”装了CUDA版,结果驱动不匹配,import torch直接报错,反而耽误时间。先用CPU版跑通全流程,确认需要GPU加速再换。

2.3 目录结构的设计

Qlib默认会在用户目录下创建.qlib文件夹存放数据和配置。这个设计在单用户场景下没问题,但如果你要管理多个数据集、或者想把数据放在大容量硬盘上,就需要自定义路径。

我习惯的目录结构是这样的:

/home/user/qlib_workspace/ ├── data/ # 原始数据 │ └── qlib_data/ # Qlib格式的数据集 ├── configs/ # 配置文件 ├── scripts/ # 自定义脚本 └── outputs/ # 回测结果、模型文件

这样规划的好处是数据与代码分离,备份和迁移都方便。设置环境变量指向自定义路径:

export QLIB_DATA=/home/user/qlib_workspace/data/qlib_data

Windows下用set QLIB_DATA=...或者在系统环境变量里配置。这个变量Qlib会自动读取,后续初始化数据时会用到。

3. 数据初始化:从下载到可用状态的全过程

3.1 官方数据集的获取方式

Qlib提供了一套预处理好的中国A股数据集,包含日频行情、基本面指标等。获取方式是通过scripts/get_data.py脚本:

python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn

这个命令会从远程仓库下载数据并解压到指定目录。国内网络下这一步可能很慢甚至中断。我的做法是先用下载工具把数据包拉到本地,再手动解压到目标目录。数据包在Qlib的GitHub release页面有提供,文件名类似qlib_data_cn_1d.zip。

解压后的目录结构长这样:

cn_data/ ├── calendars/ # 交易日历 ├── features/ # 各股票的因子数据 ├── instruments/ # 股票池定义 └── ...

每个子目录下按股票代码分文件夹,数据以二进制格式存储,读取速度比CSV快很多。这也是Qlib的一个设计亮点——用二进制格式换I/O效率,回测时加载几千只股票的历史数据几乎无感。

3.2 数据路径的配置与验证

数据下载完成后,需要告诉Qlib去哪里找。有两种方式:

第一种是初始化时指定:

import qlib qlib.init(provider_uri='/home/user/qlib_workspace/data/qlib_data/cn_data', region='cn')

第二种是写进配置文件,后续用qlib.init_from_yaml()加载。我推荐第二种,尤其是需要频繁切换数据集的时候。

验证数据是否可用,跑一段简单的查询:

from qlib.data import D # 获取沪深300成分股列表 instruments = D.instruments(market='csi300') print(len(instruments)) # 获取某只股票某段时间的收盘价 df = D.features(['SH600000'], ['$close'], start_time='2020-01-01', end_time='2020-12-31') print(df.head())

如果能看到数据输出,说明初始化成功。如果报ValueError: instrument not found,大概率是股票代码格式不对——Qlib用的是SH600000这种带交易所前缀的格式,不是600000.SH。

3.3 自定义数据的接入

官方数据集只覆盖A股,如果你要研究美股、港股或者加密货币,就需要自己准备数据。Qlib支持通过dump_bin.py脚本把CSV转成它的二进制格式。核心要求是CSV必须包含date、symbol、open、high、low、close、volume这几列。

转换命令:

python scripts/dump_bin.py dump_all \ --csv_path ./my_csv_data \ --qlib_dir ./my_qlib_data \ --include_fields open,high,low,close,volume \ --date_field_name date \ --symbol_field_name symbol

这里有个细节:CSV里的日期格式必须是YYYY-MM-DD,其他格式(如YYYY/MM/DD)会导致解析失败。我一开始用券商导出的数据,日期是20200101这种紧凑格式,转换时全部报错,后来写了个pandas脚本统一格式化才解决。

4. 跑通第一个策略:从配置到回测结果解读

4.1 工作流配置文件的编写

Qlib的核心工作流通过YAML文件定义。一个最简化的LightGBM策略配置如下:

qlib_init: provider_uri: "/home/user/qlib_workspace/data/qlib_data/cn_data" region: cn market: &market csi300 benchmark: &benchmark SH000300 data_handler_config: &data_handler_config start_time: 2015-01-01 end_time: 2020-12-31 fit_start_time: 2015-01-01 fit_end_time: 2018-12-31 instruments: *market task: model: class: LGBModel module_path: qlib.contrib.model.gbdt kwargs: loss: mse learning_rate: 0.05 num_leaves: 64 num_threads: 8 dataset: class: DatasetH module_path: qlib.data.dataset kwargs: handler: class: Alpha158 module_path: qlib.contrib.data.handler kwargs: *data_handler_config segments: train: [2015-01-01, 2018-12-31] valid: [2019-01-01, 2019-12-31] test: [2020-01-01, 2020-12-31] record: - class: SignalRecord module_path: qlib.workflow.record_temp - class: PortAnaRecord module_path: qlib.workflow.record_temp

几个关键点解释一下:

  • fit_start_time和fit_end_time是给特征归一化用的,不能和训练集时间范围混淆。归一化参数只应该用训练集的数据来拟合,否则就是未来函数。
  • Alpha158是Qlib内置的因子集,包含158个技术指标因子。如果你想用自己的因子,需要继承DataHandler类重写。
  • segments里的train/valid/test划分要严格按时间顺序,不能随机打乱,这是时序预测的基本要求。

4.2 启动回测与日志观察

配置写好后,用qrun命令启动:

qrun configs/my_lgb_config.yaml

运行过程中会输出训练日志、验证集指标、回测进度。第一次跑可能会比较慢,因为要计算158个因子。在我的工作站(8核CPU)上,沪深300成分股、5年数据,因子计算大概需要10分钟,模型训练2分钟左右。

回测完成后,结果会保存在outputs/目录下,包含:

  • 模型文件(.pkl)
  • 预测信号(pred.pkl)
  • 回测报告(report_normal_1day.pkl)
  • 分析图表(analysis_position/下的PNG)

4.3 回测指标的理解与陷阱

Qlib的PortAnaRecord会生成几个核心指标:

指标含义注意事项
年化收益策略一年的预期收益高收益往往伴随高回撤,需结合看
信息比率超额收益/跟踪误差大于1算不错,大于2要警惕过拟合
最大回撤峰值到谷底的最大亏损这是实盘最关心的指标
换手率持仓变动频率高换手意味着高交易成本

最容易踩的坑是忽略交易成本。Qlib默认的回测不考虑手续费和滑点,跑出来的收益往往虚高。实际使用时需要在配置里加上:

backtest: account: 1000000 benchmark: *benchmark exchange_kwargs: open_cost: 0.0005 close_cost: 0.0015 min_cost: 5

这里的open_cost是买入费率,close_cost是卖出费率(含印花税),min_cost是最低手续费。加上这些之后,你会发现很多高频策略的收益直接被吃掉一半。

5. 实操中绕不开的五个坑与排查思路

5.1 内存溢出:因子计算时的OOM

跑Alpha158的时候,如果股票池太大(比如全市场4000+只股票),内存占用会飙升。我遇到过16GB内存的机器直接卡死的情况。原因是Qlib在计算因子时会把所有股票的原始数据加载到内存,再做滚动窗口计算。

解决方案有三个方向:

  • 缩小股票池:用沪深300或中证500代替全市场,内存占用能降一个数量级。
  • 减少因子数量:Alpha158可以按需选择子集,不必全上。
  • 增大虚拟内存:Linux下调整swap大小,Windows下调整页面文件。但这只是权宜之计,根本还是要控制数据量。

5.2 数据对齐问题:停牌与涨跌停的处理

A股有停牌和涨跌停机制,如果回测时不处理,会出现“停牌期间还能交易”的荒谬结果。Qlib的数据集里其实有停牌标记,但默认的回测逻辑不会自动过滤。

我的做法是在策略信号生成后,加一层过滤:

# 过滤掉停牌和涨跌停的股票 from qlib.data import D trade_status = D.features(instruments, ['$trade_status'], start_time, end_time) # trade_status为0表示正常交易,1表示停牌,2表示涨跌停

然后在回测配置里设置only_tradable=True,让Qlib只对可交易的股票下单。

5.3 路径配置的常见错误

provider_uri路径写错是最常见的报错来源。几个典型症状:

  • 报FileNotFoundError:路径根本不存在,检查是否拼写错误。
  • 报ValueError: calendar not found:路径存在但缺少calendars子目录,说明数据没下载完整。
  • 报KeyError: 'SH600000':股票代码不在当前股票池里,检查instruments配置。

排查时可以用os.listdir(provider_uri)看看目录下有什么,对照Qlib的数据格式要求逐项检查。

5.4 模型训练不收敛的排查

LightGBM训练时loss不下降,通常是这几个原因:

  • 学习率太大:默认0.1,试试降到0.05或0.01。
  • 特征未归一化:Alpha158内部做了归一化,但自定义因子需要自己处理。
  • 标签泄露:检查标签计算是否用了未来数据。比如用当日收盘价算标签,但特征里也包含了当日收盘价,这就是泄露。

我习惯在训练前先跑一遍相关性分析,看看特征和标签的IC值。如果IC普遍低于0.02,说明因子有效性不足,换模型也没用。

5.5 回测结果与实盘的偏差

回测年化30%,实盘跑出来只有5%,这种落差在量化圈太常见了。除了交易成本,还有几个隐性因素:

  • 滑点:回测假设按收盘价成交,实盘可能买在最高点。
  • 流动性:小市值股票回测时成交量假设无限,实盘根本买不到量。
  • 幸存者偏差:回测用的股票池是当前成分股,已经剔除了退市股票,天然高估收益。

Qlib的回测框架可以部分模拟这些因素,但完全消除偏差是不可能的。我的经验是回测收益打五折再看待,如果打五折后还能跑赢基准,这个策略才值得进一步研究。

6. 进阶调优:让回测更接近实盘的几个配置

6.1 滚动训练与模型更新频率

上面的例子用的是静态训练——用2015到2018年的数据训练,然后预测2019到2020年。但市场风格会变,一个模型用两年不更新,效果必然衰减。

Qlib支持滚动训练(Rolling Training),配置方式是在task里加rolling参数:

task: rolling: step: 60 # 每60个交易日重新训练 window: 252 # 用过去252个交易日的数据

这样模型会定期用最新数据更新,更贴近实盘。代价是计算量成倍增加,回测时间可能从几分钟变成几小时。

6.2 多模型集成

单一模型容易过拟合,把LightGBM、LSTM、线性回归的预测结果做加权平均,往往能提升稳定性。Qlib的Ensemble类支持这个功能:

from qlib.contrib.model.ensemble import Ensemble ensemble = Ensemble([ ('lgb', lgb_model, 0.5), ('lstm', lstm_model, 0.3), ('linear', linear_model, 0.2) ])

权重的确定可以用验证集上的IC值来分配,IC高的模型给更大权重。我实测下来,三模型集成比单LightGBM的信息比率能提升0.3左右。

6.3 自定义因子的接入

Qlib内置的Alpha158虽然全面,但都是技术面因子。如果你想加入基本面因子(如PE、ROE)或者另类数据(如舆情情绪),需要自定义DataHandler。

核心是继承DataHandlerLP类,重写_load_data方法:

from qlib.data.dataset.handler import DataHandlerLP class MyHandler(DataHandlerLP): def _load_data(self, instruments, start_time, end_time): # 加载自定义因子数据 df = load_my_factors(instruments, start_time, end_time) return df

自定义因子的计算逻辑要特别注意时间对齐。比如财报数据,一季度报在4月底才公布,如果你在3月就用了一季度的ROE,那就是未来函数。正确做法是用publish_date而不是report_date来对齐。

7. 一些个人体会与后续可探索的方向

部署Qlib这件事,说难不难,说简单也不简单。难在环境配置的琐碎和数据处理的细节,简单在一旦跑通,后续的策略迭代就是改改配置文件、换换模型的事。我自己的经验是,第一次部署不要追求完美,先把官方数据集和默认配置跑通,看到回测报告出来,再逐步替换成自己的数据和策略。

另外提一点,Qlib的社区版和内部版本有差异,开源版本去掉了部分实盘交易接口和风控模块。如果你是想做实盘,还需要自己对接券商API,这部分Qlib不提供现成方案。

后续可以探索的方向包括:接入另类数据源(如卫星图像、供应链数据)、尝试强化学习做仓位管理、用Qlib的在线服务模式做实时预测。这些都需要在本地部署的基础上进一步开发,但底层的数据管理和回测框架,Qlib已经帮你搭好了。

最后分享一个小技巧:Qlib的日志系统默认输出到控制台,信息量很大。如果只想看关键信息,可以在qlib.init时设置logging_level='WARNING',这样只有警告和错误才会打印,回测日志会清爽很多。

相关新闻

WorkBuddy搭建小红书图文自动化SOP:从选题到数据回流完整指南

WorkBuddy搭建小红书图文自动化SOP:从选题到数据回流完整指南

我正式开始用WorkBuddy做小红书图文自动化的时候,心里其实没底。当时我已经被"日更"压得喘不过气:每天想选题、写文案、做图、排版、回复评论,几乎占掉所有空余时间,可产出还不稳定。后来我把整套流程拆开,用…

2026/10/20 18:07:26 阅读更多 →
腾讯云语音识别实战:半小时会议实时字幕与纪要自动生成

腾讯云语音识别实战:半小时会议实时字幕与纪要自动生成

会开完,一屋子人盯着白板,但会议纪要却要等到明天行政同事整理好再群发出去。这期间我们大概率忘了讨论到第三个人时他到底承诺了什么。我尝试过用手机录音,回头逐句听一遍再整理,半小时的会来回折腾两个小时,效率惨不…

2026/10/20 18:06:19 阅读更多 →
WorkBuddy内容量产实战:从选题到多平台分发的完整工作流

WorkBuddy内容量产实战:从选题到多平台分发的完整工作流

1. 选题荒的根源不是没灵感,而是缺少一套可复用的信息输入管道做自媒体最怕的不是写不出来,而是坐在电脑前盯着空白文档,脑子里翻来覆去就那几个老话题。我见过太多人把"选题荒"归结为"灵感不够",然后拼命刷同…

2026/10/20 18:06:19 阅读更多 →

最新新闻

ESP32隐藏射频通路:官方手册未记载的寄存器级调试与风险

ESP32隐藏射频通路:官方手册未记载的寄存器级调试与风险

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 19:19:32 阅读更多 →
Android图形系统核心:BufferQueue、VSYNC与HWC协同机制解析

Android图形系统核心:BufferQueue、VSYNC与HWC协同机制解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 19:19:32 阅读更多 →
端侧AI加速实战:NPU/TPU架构、量化和部署调优全解析

端侧AI加速实战:NPU/TPU架构、量化和部署调优全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 19:19:32 阅读更多 →
公众号约玩树洞系统源码解析:匿名会话与陪聊计费设计

公众号约玩树洞系统源码解析:匿名会话与陪聊计费设计

简介:这份资源是面向公众号运营者与陪聊、约玩类社交产品开发者的树洞系统源码,基于FastAdmin框架构建,属于全开源版本,与市面上常见的加密版不同,其api控制器目录未做加密处理,便于二次开发与调试。前端为…

2026/10/20 19:19:32 阅读更多 →
考研C++刷题训练框架:自动判题与错题归档源码解析

考研C++刷题训练框架:自动判题与错题归档源码解析

简介:面向考研学子的C编程训练源码包,汇集数据合并、求和、质数检测、指针操作、结构体封装等基础与进阶练习,适合计算机专业及需要加强编程能力的考生日常刷题、查漏补缺。包内共23个文件,包含11个cpp源代码文件、11个对应exe可执…

2026/10/20 19:19:32 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到平滑运动与智能联动

ESP32舵机控制全攻略:从PWM原理到平滑运动与智能联动

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 19:18:26 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →