Qlib Recorder 实验管理系统:MLflow 后端之上的三层实验管理与记录模板实战指南
本文基于 Qlib 官方文档 docs/component/recorder.rst 展开,系统讲解 Qlib 内置的实验管理系统(QlibRecorder):ExpManager / Experiment / Recorder 三层结构、全局入口 R 的高层 API、MLflow 后端的具体实现细节,以及 SignalRecord、SigAnaRecord、PortAnaRecord 三类记录模板如何自动产出预测结果、IC 分析与回测报告,并结合源码逐层剖析每个 API 背后的真实行为,帮助你在量化研究中规范地追踪、复现和对比每一次模型实验。
一、系统概览:实验管理的三层结构
Qlib 包含一个名为 QlibRecorder 的实验管理系统,旨在帮助用户高效地管理实验、分析实验结果。该系统由三个层次的组件构成:
ExperimentManager(代码中类名为ExpManager):管理所有实验的顶层类;Experiment:实验类,每个实例负责一个实验;Recorder:记录器类,每个实例负责单次运行(single run)的详细记录。
系统的整体结构如下:
ExperimentManager
- Experiment 1
- Recorder 1
- Recorder 2
- ...
- Experiment 2
- Recorder 1
- Recorder 2
- ...
- ...
该体系定义了一套接口,并提供了一个基于机器学习平台 MLflow 的具体实现 MLflowExpManager。用户只需将 ExpManager 实现设置为 MLflowExpManager(这本身就是 Qlib 的默认配置,见 qlib/config.py),即可在实验完成后执行 mlflow ui 命令可视化查看实验结果,具体用法参考 MLflow 官方 CLI 文档。
从源码注释(qlib/workflow/init.py)可以看出,Qlib 选择不直接裸用 MLflow 而封装一层的核心动机有三点:
- 更好的对象化设计:相比 MLflow 中到处传
run_id的方式,Qlib 提供了带丰富方法的Recorder对象,log、start等接口更直观; - 更贴合场景的附加特性:例如在 run 开始时自动记录未提交的代码 diff、提供面向 Python 对象的
log_object/load_object(而非 MLflow 的log_artifact/download_artifact); - 支持多样化后端:接口与后端解耦,理论上可以更换存储实现而无需改动上层代码。
二、全局入口 R:QlibRecorder 高层 API
QlibRecorder 为实验管理系统提供了高层 API。这些接口被封装在 Qlib 的全局变量 R 中,用户导入后即可直接使用:
from qlib.workflow import R
R 并非普通实例,而是一个带校验的包装器 RecorderWrapper(见 qlib/workflow/init.py#L656-L681):如果在已有实验处于激活状态时重新执行 qlib.init,它会抛出 RecorderInitializationError,防止实验的存储位置(uri)在运行中途被改写。R 的真正注册发生在 qlib.init 触发的 Config.register 中:系统按全局配置实例化 exp_manager,用其构造 QlibRecorder 并挂载到 R 上。
2.1 启动与结束实验:start / start_exp / end_exp
R.start 是一个上下文管理器,只能配合 with 语句使用。正常退出时 recorder 状态被置为 FINISHED;发生异常时自动置为 FAILED 并向上抛出。完整参数语义(源自 QlibRecorder.start 源码):
from qlib.workflow import R
# 启动新实验和新 recorder
with R.start(experiment_name='test', recorder_name='recorder_1'):
model.fit(dataset)
R.log_metrics(train_loss=0.33, step=1)
# 恢复(resume)之前同名实验下的 recorder,
# 注意:必须给出与之前完全一致的 experiment 和 recorder 名称
with R.start(experiment_name='test', recorder_name='recorder_1', resume=True):
...
| 参数 | 说明 |
|---|---|
experiment_id / experiment_name |
要启动的实验的 id / 名称 |
recorder_id / recorder_name |
实验下要启动的 recorder 的 id / 名称 |
uri |
实验的 tracking uri,所有 artifacts/metrics 都存储在该 uri 下。默认值来自 qlib.config;该参数不会修改配置文件中的默认值,因此同一实验再次调用时需传相同值,否则可能出现 uri 不一致 |
resume |
是否恢复(resume)给定实验下给定名称的 recorder |
如果需要手动控制生命周期,可以使用更底层的 start_exp / end_exp 组合:
R.start_exp(experiment_name='test', recorder_name='recorder_1')
... # further operations
R.end_exp('FINISHED') # 等价于 R.end_exp(Recorder.STATUS_FI)
end_exp(status) 接收的 status 取值包括 SCHEDULED、RUNNING、FINISHED、FAILED,对应 Recorder 类中定义的状态常量(qlib/workflow/recorder.py#L36-L40):STATUS_S、STATUS_R、STATUS_FI、STATUS_FA。
2.2 获取实验与记录器:get_exp / get_recorder / list_*
R.get_exp(experiment_id=None, experiment_name=None, create=True, start=False) 是最核心的检索 API,其完整判定逻辑在 QlibRecorder.get_exp 源码 中有详细描述:
create=True(默认)时,找不到指定实验会自动创建;若未指定 id/name 且当前无激活实验,则创建默认实验;create=False时只检索,找不到则抛错;start=True时,若实验尚未激活会将其设为激活状态(该参数主要为R.log_params等自动启动实验的接口设计)。
典型用法:
# 用法 1:在 with 块内取当前激活实验
with R.start('test'):
exp = R.get_exp()
recorders = exp.list_recorders()
# 用法 2:取指定名称的实验
with R.start('test'):
exp = R.get_exp(experiment_name='test1')
# 用法 3:不带参数 -> 返回(或创建)默认实验
exp = R.get_exp()
# 用法 4:取指定实验
exp = R.get_exp(experiment_name='test')
# 用法 5:仅检索,不创建
exp = R.get_exp(create=False)
R.get_recorder(...) 用于获取 recorder:若存在激活 recorder 且未指定 id/name,返回激活 recorder;指定 id 但无激活实验上下文时必须同时给出 experiment_name,否则会报错(详见 QlibRecorder.get_recorder 源码)。当多个 recorder 匹配查询(例如按名称查询)时,若使用 MLflow 后端,将返回 start_time 最新的那个——因为底层依赖 MLflow search_runs 默认的按 start_time DESC 排序保证。
此外还有:
R.list_experiments():列出所有未被删除的实验,返回dict(name -> experiment);R.list_recorders(experiment_id=None, experiment_name=None):列出指定实验下所有 recorder,返回dict(id -> recorder);若不给实验 id/name,会先取(必要时创建)默认实验再列出其 recorder;R.delete_exp(...)、R.delete_recorder(...):按 id 或 name 删除,至少需提供一个。
R.search_records(experiment_ids, **kwargs) 返回符合搜索条件的 pandas DataFrame,其中每个 metric、param、tag 会展开为 metrics.*、params.*、tags.* 列。MLflow 实现下支持 filter_string、run_view_type、max_results、order_by 等参数,例如:
R.log_metrics(m=2.50, step=0)
records = R.search_records([experiment_id], order_by=["metrics.m DESC"])
该调用链最终落到 MLflowExpManager.search_records 的 client.search_runs(...),run_view_type 默认 1(ACTIVE_ONLY),max_results 默认 100000。
2.3 记录参数、指标、标签与对象
以下 API 遵循同一模式:存在激活 recorder 时经其记录;不存在时自动创建默认实验和新 recorder 再记录。
# 记录参数
with R.start('test'):
R.log_params(learning_rate=0.01)
# 也可以脱离 with 块直接调用(自动创建默认实验+recorder)
R.log_params(learning_rate=0.01)
# 记录指标
R.log_metrics(train_loss=0.33, step=1)
# 设置标签
R.set_tags(release_version="2.2.0")
# 保存对象(两种互斥方式:传本地路径 或 直接传对象)
with R.start(experiment_name='test'):
pred = model.predict(dataset)
R.save_objects(**{"pred.pkl": pred}, artifact_path='prediction')
rid = R.get_recorder().id
# 之后任意时刻可从 artifact 加载回来
R.get_recorder(recorder_id=rid).load_object("prediction/pred.pkl")
# 保存本地文件/目录
with R.start(experiment_name='test'):
R.save_objects(local_path='results/pred.pkl', artifact_path="prediction")
注意 R.save_objects 中 local_path 与 **kwargs 二选一,同时提供会抛出 ValueError(源码校验逻辑)。另有 R.log_artifact(local_path, artifact_path=None) 与 R.download_artifact(path, dst_path=None) 处理原始文件级别的 artifact 上传/下载。
2.4 uri 管理:get_uri / set_uri / uri_context
R.get_uri():获取当前实验管理器的 tracking uri;R.set_uri(uri):重置默认 uri(注意:uri 指向文件路径时必须使用绝对路径,后端不支持"~/mlruns/"这类写法);R.uri_context(uri):上下文管理器,临时切换默认 uri,退出后自动还原。
从源码结构看,ExpManager.default_uri 实际上与 Qlib 全局配置 C.exp_manager["kwargs"]["uri"] 共享同一份数据(qlib/workflow/expm.py#L282-L304),运行时生效的 uri 优先取实验期间的“specific uri”(_active_exp_uri),否则回落到默认 uri。默认 uri 为 file: 加当前工作目录下的 mlruns,默认实验名为 Experiment(qlib/config.py)。
三、Experiment Manager 层:ExpManager 与 MLflowExpManager
ExpManager 模块负责管理不同实验,其多数 API 与 QlibRecorder 类似(R 层基本是透传代理),最重要的 API 是 get_exp。实现类 MLflowExpManager 的关键行为:
- client 惰性构造:
self.client属性每次按需创建MlflowClient(tracking_uri=self.uri),仓库内 tests/dependency_tests/test_mlflow.py 中有专门测试确保创建 client 的速度不会成为瓶颈; - 实验的 get-or-create 与并发安全:_get_or_create_exp 先尝试检索,失败后自动创建。由于 MLflow 本身在并发记录时不加锁,Qlib 在接口层做了补充:当 uri 是
file:方案时,用FileLock串行化创建过程;对http等其他方案则通过捕获ExpAlreadyExistError后回查来避免创建冲突; list_experiments会依据 MLflow 大版本选择search_experiments(v2+)或list_experiments(v1),只返回ACTIVE_ONLY的实验;delete_exp支持按 id 或 name 删除,删除前会校验实验是否存在。
create_exp、delete_exp、search_records 等其余接口的完整签名参见官方 API 参考文档 docs/reference/api.rst。
四、Experiment 层:单实验的操控
Experiment 类负责单个实验的全部操作,包括 start、end 等基本方法,以及与 recorder 相关的方法 get_recorder、list_recorders。MLflow 实现类 MLflowExperiment 的关键细节:
start:给定recorder_name(缺省为mlflow_recorder),resume=True时复用既有 recorder,否则create_recorder新建,然后start_run()并设为激活 recorder;list_recorders(rtype="dict", status=None, filter_string=""):底层调用search_runs(默认按start_time DESC, run_id排序),支持按status过滤(如list_recorders(status=Recorder.STATUS_FI)只看成功的 run)和 MLflow 过滤串(如'params."my_param"="a" and tags."my_tag"="b"')。从源码结构看,max_results上限被设为 50000(exp.py 中的UNLIMITED常量),这是 MLflow 本身的列表上限;get_recorder的 create/start 语义与R.get_recorder类似,但面向实验粒度;search_records、delete_recorder(按 id 或 name 删除 run)同样在此层提供。
默认实验(Default Experiment)
Qlib 提供了一个默认 Experiment:当用户使用 log_metrics、get_exp 等 API 而未指定实验时,系统会自动创建并使用它。默认实验名在 qlib 配置文件(C.exp_manager.kwargs.default_exp_name)或 qlib 初始化 时设置,默认值为 Experiment。使用默认实验时运行日志中会有相应提示。
五、Recorder 层:单次运行(run)的详细记录
Recorder 类负责单次 run 的细粒度操作,如 log_metrics、log_params 等,其设计目标是帮助用户轻松追踪一次运行中产出的结果与过程信息。QlibRecorder 未覆盖的重要 API(定义在 qlib/workflow/recorder.py 中):
recorder.list_artifacts(artifact_path=None) # 列出该 run 的所有 artifact 路径
recorder.list_metrics() # 返回已记录的 metrics 字典
recorder.list_params() # 返回已记录的 params 字典
recorder.list_tags() # 返回已记录的 tags 字典
save_objects、load_object、log_artifact、download_artifact、delete_tags 等其余接口参见 docs/reference/api.rst。
5.1 start_run:自动记录代码 diff 与环境信息
MLflowRecorder.start_run 在启动 run 时做了不少 MLflow 原生 API 不会做的事,这也是 Qlib 封装层价值的集中体现:
- 设置 tracking uri 并
mlflow.start_run,把run_id、artifact_uri、开始时间、状态(RUNNING)写回 recorder; - 自动记录未提交的代码:MLflow 原生只记录当前仓库的 commit id,但研究代码常常有大量未提交改动。_log_uncommitted_code 会执行
git diff、git status、git diff --cached三条命令,把输出分别保存为code_diff.txt、code_status.txt、code_cached.txt三个 artifact,保证实验可复现; - 自动记录运行上下文:
log_params记录cmd-sys.argv(产生该实验的完整命令行),并记录所有以_QLIB_开头的环境变量; - 异步日志:
log_params、log_metrics、set_tags都通过AsyncCaller装饰(源码)提交到异步队列,避免记录操作阻塞训练主流程。代价是上传结果可能有延迟、时间戳不够精确;end_run时会先async_log.wait()排空队列再调用mlflow.end_run(status),否则 MLflow 会报错(end_run 实现)。
另外,由于使用 qrun 时参数串可能较长,Qlib 把 MLflow 的参数值长度上限从 500 放宽到了 1000(recorder.py#L24-L25)。
5.2 save_objects / load_object:基于 pickle 的对象存取
save_objects(local_path=None, artifact_path=None, **kwargs):local_path为目录时整体log_artifacts,为文件时log_artifact;直接传对象时先经Serializable.general_dump序列化到临时目录再上传,随后清理临时目录(实现);load_object(name, unpickler=pickle.Unpickler):下载 artifact 后反序列化返回,并支持传入自定义unpickler以适配特殊加载需求;异常统一包装为LoadObjectError。
get_local_dir() 还能解析出本地文件系统后端下该 recorder 的目录路径(非本地存储会抛 RuntimeError)。
六、Record Template:标准化的实验结果生成
RecordTemp 类用于以统一格式生成实验结果,如 IC 与回测分析。record_temp.py 中提供了多个模板类,其中三个核心模板:
SignalRecord:生成模型的prediction结果,保存pred.pkl(以及数据集为DatasetH时的label.pkl);SigAnaRecord:生成模型的IC、ICIR、Rank IC、Rank ICIR指标(artifact 路径前缀sig_analysis);开启ana_long_short时还会输出长短期年化收益/夏普等;PortAnaRecord:生成backtest结果(artifact 路径前缀portfolio_analysis),保存各频率的report_normal_*.pkl、positions_normal_*.pkl、port_analysis_*.pkl等,并把风险指标打平后log_metrics到 recorder。更完整的策略与回测机制可参考 策略文档。
除三者外,源码中还有面向多轮回测稳健性的 MultiPassPortAnaRecord(打乱首日预测分数随机化初始仓位,统计 annualized_return、information_ratio 的 mean/std)与高频场景的 HFSignalRecord(在 IC 之外补充 Long/Short precision、Long-Short Average Return 等指标)。
6.1 手动计算 IC / Rank IC / Long-Short Return
SigAnaRecord 的核心计算可以脱离模板直接复用,适合自己已有 pred 与 label 的场景:
from qlib.contrib.eva.alpha import calc_ic, calc_long_short_return
ic, ric = calc_ic(pred.iloc[:, 0], label.iloc[:, 0])
long_short_r, long_avg_r = calc_long_short_return(pred.iloc[:, 0], label.iloc[:, 0])
在 SigAnaRecord._generate 中,其指标定义为:IC = ic.mean()、ICIR = ic.mean() / ic.std()、Rank IC = ric.mean()、Rank ICIR = ric.mean() / ric.std();长短期指标则按 ann_scaler(默认 252)年化:Long-Short Ann Return = long_short_r.mean() * ann_scaler、Long-Short Ann Sharpe = long_short_r.mean() / long_short_r.std() * ann_scaler**0.5 等。
6.2 手动回测与风险分析
PortAnaRecord 的本质是基于自己的 prediction 与 label 做回测:
from qlib.contrib.strategy.strategy import TopkDropoutStrategy
from qlib.contrib.evaluate import (
backtest as normal_backtest,
risk_analysis,
)
# backtest
STRATEGY_CONFIG = {
"topk": 50,
"n_drop": 5,
}
BACKTEST_CONFIG = {
"limit_threshold": 0.095,
"account": 100000000,
"benchmark": BENCHMARK,
"deal_price": "close",
"open_cost": 0.0005,
"close_cost": 0.0015,
"min_cost": 5,
}
strategy = TopkDropoutStrategy(**STRATEGY_CONFIG)
report_normal, positions_normal = normal_backtest(pred_score, strategy=strategy, **BACKTEST_CONFIG)
# analysis
analysis = dict()
analysis["excess_return_without_cost"] = risk_analysis(report_normal["return"] - report_normal["bench"])
analysis["excess_return_with_cost"] = risk_analysis(report_normal["return"] - report_normal["bench"] - report_normal["cost"])
analysis_df = pd.concat(analysis) # type: pd.DataFrame
print(analysis_df)
在模板内部,PortAnaRecord 未显式传 config 时使用一套日线交易默认配置(record_temp.py 源码):策略为 TopkDropoutStrategy(topk=50, n_drop=5, signal=<PRED>),执行器为 SimulatorExecutor(time_per_step="day", generate_portfolio_metrics=True),回测账户 1 亿元、基准 SH000300,交易成本与上面示例一致(limit_threshold=0.095、open_cost=0.0005、close_cost=0.0015、min_cost=5)。其中 <PRED> 是占位符,_generate 时会用 recorder 中保存的 pred.pkl 替换;若未设置 start_time / end_time,会自动从预测数据的日期范围推断,且 end_time 会向前回移一个交易日(Qlib 需要额外的一个日历步来确定 bar 的右边界),并打印相应 warning。更多 Record Template API 参见 docs/reference/api.rst。
七、实战串联:一次完整的实验工作流
examples/workflow_by_code.py 演示了 R 与三类记录模板在纯代码方式下的完整串联(与 qrun XXX.yaml 配置文件方式几乎等价):
import qlib
from qlib.constant import REG_CN
from qlib.utils import init_instance_by_config, flatten_dict
from qlib.workflow import R
from qlib.workflow.record_temp import SignalRecord, PortAnaRecord, SigAnaRecord
from qlib.tests.data import GetData
from qlib.tests.config import CSI300_BENCH, CSI300_GBDT_TASK
if __name__ == "__main__":
provider_uri = "~/.qlib/qlib_data/cn_data"
GetData().qlib_data(target_dir=provider_uri, region=REG_CN, exists_skip=True)
qlib.init(provider_uri=provider_uri, region=REG_CN)
model = init_instance_by_config(CSI300_GBDT_TASK["model"])
dataset = init_instance_by_config(CSI300_GBDT_TASK["dataset"])
# 回测配置:executor / strategy / backtest 三段
port_analysis_config = {
"executor": {"class": "SimulatorExecutor", "module_path": "qlib.backtest.executor",
"kwargs": {"time_per_step": "day", "generate_portfolio_metrics": True}},
"strategy": {"class": "TopkDropoutStrategy", "module_path": "qlib.contrib.strategy.signal_strategy",
"kwargs": {"signal": (model, dataset), "topk": 50, "n_drop": 5}},
"backtest": {"start_time": "2017-01-01", "end_time": "2020-08-01",
"account": 100000000, "benchmark": CSI300_BENCH,
"exchange_kwargs": {"freq": "day", "limit_threshold": 0.095, "deal_price": "close",
"open_cost": 0.0005, "close_cost": 0.0015, "min_cost": 5}},
}
# start exp
with R.start(experiment_name="workflow"):
R.log_params(**flatten_dict(CSI300_GBDT_TASK)) # 记录全部超参
model.fit(dataset)
R.save_objects(**{"params.pkl": model}) # 保存训练好的模型
recorder = R.get_recorder()
sr = SignalRecord(model, dataset, recorder); sr.generate() # 生成 pred.pkl / label.pkl
sar = SigAnaRecord(recorder); sar.generate() # 生成 IC / Rank IC 分析
par = PortAnaRecord(recorder, port_analysis_config, "day") # 生成回测报告
par.generate()
在配置方式下,同样的模板通过 yaml 的 record 段声明,例如 examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml:
task:
record:
- class: SignalRecord
module_path: qlib.workflow.record_temp
kwargs:
model: <MODEL>
dataset: <DATASET>
- class: SigAnaRecord
module_path: qlib.workflow.record_temp
kwargs:
ana_long_short: False
ann_scaler: 252
- class: PortAnaRecord
module_path: qlib.workflow.record_temp
kwargs:
config: *port_analysis_config
其中 <MODEL>、<DATASET>、<PRED> 为工作流占位符,由 Qlib 在运行时自动填充。该模板类继承自 ACRecordTemp(自动检查型模板):generate 时先 check 依赖文件是否齐全(SigAnaRecord/PortAnaRecord 的 depend_cls 均指向 SignalRecord,即依赖 pred.pkl、label.pkl),缺失则跳过并告警;配合 skip_existing=True 还能在产物已存在时直接跳过重新生成,适合断点续跑。
运行完成后,所有实验数据(params、metrics、tags、artifacts、代码 diff)都落在默认 uri(当前工作目录的 mlruns)中,执行 mlflow ui 即可跨实验对比各 recorder 的 IC、ICIR、Rank IC 以及 1d.annualized_return、1d.information_ratio 等回测指标。
八、已知限制(Known Limitations)
- 对象基于 pickle 保存:
save_objects/load_object底层使用 pickle 序列化,当保存对象的环境与加载对象的环境不一致(如依赖库版本、注册表差异)时可能出现加载问题。加载时可通过load_object的unpickler参数传入自定义反序列化器缓解。
九、相关源码与文档索引
| 内容 | 路径 |
|---|---|
| 本文档对应的官方文档 | docs/component/recorder.rst |
全局入口 R 与 QlibRecorder 全部高层 API |
qlib/workflow/init.py |
ExpManager / MLflowExpManager |
qlib/workflow/expm.py |
Experiment / MLflowExperiment |
qlib/workflow/exp.py |
Recorder / MLflowRecorder |
qlib/workflow/recorder.py |
RecordTemp 及 Signal / SigAna / PortAna 模板 |
qlib/workflow/record_temp.py |
默认 exp_manager 配置(uri、默认实验名) |
qlib/config.py |
| 完整代码工作流示例 | examples/workflow_by_code.py |
| 配置方式示例(LightGBM + Alpha158) | examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml |
| MLflow 依赖与 client 创建性能测试 | tests/dependency_tests/test_mlflow.py |
| 实验管理相关 API 参考 | docs/reference/api.rst |
综上,Qlib 的实验管理系统在 MLflow 之上构建了一个“Manager - Experiment - Recorder”的三层对象模型:用户通过全局 R 以最少的心智负担完成实验的启动、参数/指标记录与对象存取;底层实现则自动补全了代码 diff、命令行、环境变量等复现信息;再配合 SignalRecord / SigAnaRecord / PortAnaRecord 记录模板,一次模型工作流即可沉淀出结构统一、可跨实验横向对比的预测结果、信号分析与回测报告。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00