Linux dm-cache 设备映射缓存目标:架构、工作模式与配置实操详解
dm-cache 是 Linux Device Mapper 框架下的一个块设备缓存目标(cache target),由 Joe Thornber、Heinz Mauelshagen 与 Mike Snitzer 编写。它以 SSD 等小容量高速设备为缓存,动态地把慢速大容量块设备(如机械硬盘)上的热点数据迁移到缓存设备上,从而在不改动上层文件系统与应用的条件下提升整体 IO 性能。本文基于内核源码树中的官方文档 Documentation/admin-guide/device-mapper/cache.rst 展开,并结合内核源码 drivers/md/dm-cache-target.c、drivers/md/dm-cache-metadata.c 及配套的 cache-policies.rst,系统讲解 dm-cache 的三设备模型、三种工作模式、固定块大小约束、替换策略、target 构造参数、状态输出格式、控制消息,并给出可直接落地的 dmsetup 配置示例。读完本文你将掌握如何正确选择缓存模式与块大小、如何通过 DM table 构建缓存设备、如何解读缓存运行状态,以及如何通过消息机制调整迁移阈值或做缓存块失效(invalidation)。
一、dm-cache 简介与适用场景
dm-cache 的目标是提升一个慢速块设备的性能:把一部分数据动态迁移到更小、更快的设备上(例如把机械盘上的热数据放到 SSD)。作为一个 device-mapper target,它可以被插入到 dm 栈的不同层次中,例如位于 thin-provisioning pool 的数据设备之上,为精简供给卷提供缓存加速。
文档同时指出一个客观的定位说明:与虚拟内存系统结合得更紧密的缓存方案理论上会获得更好的性能,dm-cache 是一个通用型设备映射层方案。也就是说,dm-cache 的价值更多体现在灵活性与普适性上,而不在"算法效率极致"这一维度上,这有助于读者对它的能力边界建立准确预期。
与缓存目标绑定非常紧密的两个子系统:
- 元数据格式复用:该 target 复用了精简供给(thin-provisioning)所使用的元数据库。相关背景可参考 Documentation/admin-guide/device-mapper/persistent-data.rst。
- 策略插件机制:"哪些数据需要迁移、何时迁移"的决策被交给可插拔的策略模块(policy)。内核已提供若干策略,社区也可以为特定 IO 场景(例如虚拟机镜像服务器)贡献新的策略。
二、核心术语:迁移 / 提升 / 降级
文档定义了三组基本概念,理解它们是读懂后续所有设计的前提:
- 迁移(Migration):把一个逻辑块的主副本(primary copy)从一个设备移动到另一个设备。
- 提升(Promotion):从慢速设备(origin)迁移到快速设备(cache)。
- 降级(Demotion):从快速设备(cache)迁移到慢速设备(origin)。
需要特别强调的是:origin 设备上始终保留逻辑块的一个副本。这个副本可能已经过期(out of date),也可能与 cache 设备上的副本保持同步——具体行为取决于所采用的策略与工作模式。这是 dm-cache"缓存并非移动数据"语义的关键:origin 永远是数据的权威锚点之一。
三、设计细节
3.1 三个子设备
dm-cache target 由三个块设备构造而成:
- origin 设备:大而慢的数据源设备。
- cache 设备:小而快的缓存数据设备。
- metadata 设备:小容量元数据设备,记录哪些块在缓存中、哪些块是脏的(dirty),以及供策略对象使用的额外提示(hints)。
把元数据单独放一个设备而非塞进 cache 设备,是为了让卷管理器(volume manager)能对它做差异化配置——例如做成镜像以获得额外健壮性。注意约束:一块 metadata 设备只能被一个 cache 设备使用。
从源码结构看,三个设备在 target 的构造参数解析中分别对应独立的解析函数:parse_metadata_dev、parse_cache_dev、parse_origin_dev(见 drivers/md/dm-cache-target.c)。其中元数据设备大小超过阈值时内核仅给出警告("excess space will not be used"),多余的容量不会被使用。
3.2 固定块大小及其权衡
origin 设备被划分为固定大小的块。该块大小在首次创建 cache 时配置(之后不能修改),文档给出的经验值是 256KB~1024KB。合法取值范围与约束为:
- 最小值:64 sectors(32KB);
- 最大值:2097152 sectors(1GB);
- 必须是 64 sectors(32KB)的整数倍。
源码中这一校验由宏与 parse_block_size() 共同落实(drivers/md/dm-cache-target.c、drivers/md/dm-cache-target.c):
#define DATA_DEV_BLOCK_SIZE_MIN_SECTORS (32 * 1024 >> SECTOR_SHIFT) /* 64 sectors = 32KB */
#define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT) /* 2097152 sectors = 1GB */
if (kstrtoul(dm_shift_arg(as), 10, &block_size) || !block_size ||
block_size < DATA_DEV_BLOCK_SIZE_MIN_SECTORS ||
block_size > DATA_DEV_BLOCK_SIZE_MAX_SECTORS ||
block_size & (DATA_DEV_BLOCK_SIZE_MIN_SECTORS - 1)) {
*error = "Invalid data block size";
return -EINVAL;
}
if (block_size > ca->cache_sectors) {
*error = "Data block size is larger than the cache device";
return -EINVAL;
}
可见内核除了校验上下限与对齐要求之外,还额外拒绝"块大小大于整个 cache 设备"的非法配置。
固定块大小显著简化了 target 实现,但本质上是一种折中:
- 块过大:即使只有块内一小部分被频繁访问,整块也会被提升进缓存,浪费宝贵的缓存空间;
- 块过小:会放大元数据开销(无论是核心态内存还是磁盘上的元数据)。
因此块大小的选择需要在"缓存空间利用率"与"元数据开销"之间寻找平衡。
3.3 三种缓存工作模式
dm-cache 支持三种工作模式:writeback、writethrough 与 passthrough。
| 模式 | 行为 | 适用场景 |
|---|---|---|
| writeback(默认) | 对已缓存块的写只落到 cache 设备,并在元数据中把该块标记为脏(dirty) | 追求最佳写性能,能容忍异常掉电时丢失少量最近写入数据 |
| writethrough | 对已缓存块的写必须同时写入 origin 与 cache 设备后才算完成,干净块保持干净 | 对数据可靠性要求较高,写缓存块不会产生与 origin 不一致的内容 |
| passthrough | 所有读都由 origin 提供(读全部未命中缓存),所有写都转发到 origin;对已缓存块的写命中会使对应 cache 块失效(invalidate) | 缓存内容与 origin 的相干性(coherency)无法确认的场合,如回滚底层存储快照后激活缓存 |
passthrough 模式有三条重要性质需要记牢:
- 进入 passthrough 前缓存必须是干净的(clean),否则内核会拒绝:源码中的报错为
"%s: cannot enter passthrough mode unless all blocks are clean"(见 drivers/md/dm-cache-target.c)。 - passthrough 允许在一个不需要担心相干性的前提下激活缓存设备:已经存在的相干性会被维持,但由于写操作不断发生,缓存会逐渐"冷却"。
- 后续如果缓存的相干性得到确认(或通过
invalidate_cblocks消息主动建立),可以在缓存仍温热(still warm)的状态下把它切回 writethrough / writeback 模式;否则可先丢弃缓存内容再切换到目标模式。
此外内核在异常关闭后恢复时也有兜底保护:源码中 "%s: unable to resume into passthrough mode after unclean shutdown" 表明非正常关机后不允许直接以 passthrough 模式恢复(见 drivers/md/dm-cache-target.c)。
为了清理 cache 并做好退役准备,内核提供了一个简单的 cleaner 策略:它会将缓存中所有脏块写回(write back),常用于退役一块缓存或收缩缓存设备。收缩(shrink)cache 快设备时,要求被移除区域内所有 cache 块都必须是干净的;若被移除区域仍含脏块,resize 会失败。因此在把缓存快设备体积缩小之前,务必先让缓存彻底变干净——这在 writeback 模式下尤为关键(writethrough 与 passthrough 模式本来就维持缓存干净,不存在该风险)。文档同时预告了未来的能力:支持按阈值部分清理缓存(partial clean),以便在 resize 期间保持缓存温热并继续运行于 writeback 模式。
3.4 迁移节流(migration throttling)
在 origin 与 cache 设备之间迁移数据会消耗带宽。用户可以通过设置节流阈值,防止某一时刻发生过量的迁移。当前实现尚未考虑同时进行的普通 IO 流量对设备的占用(文档注明这是未来需要改进的方向,避免在 IO 高峰时段执行迁移)。
现阶段通过消息 migration_threshold <#sectors> 设置"单次允许迁移的最大扇区数":
- 默认值为 2048 sectors(1MB);
- 源码中对应
DEFAULT_MIGRATION_THRESHOLD 2048,在缓存构造时赋给cache->migration_threshold(见 drivers/md/dm-cache-target.c、drivers/md/dm-cache-target.c); - 通过
dmsetup message下发后由消息处理代码更新(见 drivers/md/dm-cache-target.c)。
从源码看,节流逻辑还结合了设备的空闲(idle)判定:当 IO 空闲且当前待迁移量不超过阈值时才执行迁移(见 drivers/md/dm-cache-target.c)。
3.5 磁盘元数据的落盘时机
- 磁盘元数据在每个 FLUSH 或 FUA 的 bio 写入时提交(commit);
- 如果一直没有这类请求,则每秒钟自动提交一次。
这意味着 cache 的行为类似一块带易失性写缓存的物理磁盘:一旦断电,可能丢失少量最近的写入。但无论发生何种崩溃,元数据本身应当始终是自洽的(consistent)。
另一个关键设计是脏标记是"提示"而非严格实时状态:cache 块的 dirty 状态变化过于频繁,不适合每次都在线更新。常规操作下,dirty 状态会在 dm 设备被 suspend 时写盘;如果系统崩溃,重启后所有 cache 块会一律被假定为脏。这一保守策略牺牲了崩溃后的小部分热数据信息,换来了元数据一致性的简单与可靠。
策略插件还可以为每个 cache 块存放一小段提示数据(per-block policy hints),长度由策略自定但应尽量小。与 dirty 标记类似,这段数据在崩溃后会丢失,因此策略必须永远能退回到一个安全的默认值。注意:策略提示只影响性能,不影响正确性("Policy hints affect performance, not correctness")。
3.6 策略消息与丢弃状态位图
不同策略有不同的专属可调参数,dm 通过统一的 device-mapper 消息机制来读写它们(文档指出 sysfs 接口也可行,但目前走消息通道)。消息的通用语义见后文"控制消息"一节,各策略专属参数详见 Documentation/admin-guide/device-mapper/cache-policies.rst。
在迁移时,如果已知某个块已被 discard,就可以避免拷贝数据。典型场景是 mkfs 丢弃整个块设备。为此 dm-cache 保存了一张追踪块 discard 状态的位图(bitset)。由于需要记录整块 origin 设备的 discard 状态(对比 dirty 位图只需要覆盖更小的 cache 设备),该位图允许使用与 cache 块不同的块大小。
四、Target 接口:构造、状态与消息
4.1 构造函数(CTR)
构造 cache target 的完整命令行语法为:
cache <metadata dev> <cache dev> <origin dev> <block size>
<#feature args> [<feature arg>]*
<policy> <#policy args> [policy args]*
参数说明:
| 参数 | 含义 |
|---|---|
| metadata dev | 保存持久元数据的快设备 |
| cache dev | 保存缓存数据块的快设备 |
| origin dev | 保存原始数据块的慢设备 |
| block size | 缓存单元大小,单位 sector |
| #feature args | 传入的 feature 参数个数 |
| feature args | writethrough 或 passthrough(默认是 writeback) |
| policy | 要使用的替换策略名 |
| #policy args | 传给策略的 key/value 对参数个数(须为偶数) |
| policy args | 传给策略的 key/value 对,例如 sequential_threshold 1024 |
从源码构造函数的注释可以确认 target 参数解析的完整顺序与三个设备的打开方式(drivers/md/dm-cache-target.c)。默认特征在 init_features() 中初始化(drivers/md/dm-cache-target.c):工作模式默认 writeback(CM_IO_WRITEBACK)、元数据版本 1、discard 下发默认开启(discard_passdown = true)。
可选 feature 参数:
| feature 参数 | 说明 |
|---|---|
| writethrough | 透写式缓存:禁止 cache 块内容与 origin 块内容不一致。不指定时(默认行为)为性能考虑会在稍后把 cache 块内容写回 origin,因此两者内容可能不同 |
| passthrough | 降级模式,适用于各种缓存相干性场景(例如回滚底层存储的快照)。读写总是去 origin;若写命中某个已被缓存的 origin 块,则对应的 cache 块被失效。启用 passthrough 前缓存必须是干净的 |
| metadata2 | 使用第 2 版元数据:把 dirty 位存放在一颗独立的 btree 中,从而提升 cache 关闭(shutdown)的速度 |
| no_discard_passdown | 禁止把 discard 从 cache 下传到 origin 的数据设备 |
补充两点与"default"策略相关的官方提醒:
- 名为
default的策略总是被注册,它是"当前我们认为综合表现最好的策略"的别名; - 由于不同内核版本之间 default 策略可能变化,如果你依赖某个具体策略的特性,务必在构造参数中按名称显式指定该策略。
在当前的源码树中,default 策略实际指向 smq 策略(详见后文第五节),历史遗留的 mq 名字也已成为 smq 的别名。
4.2 Status 输出
查询 cache 设备状态时(例如 dmsetup status),输出格式为:
<metadata block size> <#used metadata blocks>/<#total metadata blocks>
<cache block size> <#used cache blocks>/<#total cache blocks>
<#read hits> <#read misses> <#write hits> <#write misses>
<#demotions> <#promotions> <#dirty> <#features> <features>*
<#core args> <core args>* <policy name> <#policy args> <policy args>*
<cache metadata mode>
各字段含义:
| 字段 | 含义 |
|---|---|
| metadata block size | 每块元数据块的固定大小,单位 sector |
| #used metadata blocks | 已使用的元数据块数 |
| #total metadata blocks | 元数据块总数 |
| cache block size | cache 设备的可配置块大小,单位 sector |
| #used cache blocks | 常驻缓存中的块数 |
| #total cache blocks | cache 块总数 |
| #read hits | READ bio 被映射到 cache 的次数 |
| #read misses | READ bio 被映射到 origin 的次数 |
| #write hits | WRITE bio 被映射到 cache 的次数 |
| #write misses | WRITE bio 被映射到 origin 的次数 |
| #demotions | 块被移出 cache 的次数 |
| #promotions | 块被移入 cache 的次数 |
| #dirty | 缓存中与 origin 不一致的块数 |
| #feature args | 其后 feature args 的个数 |
| feature args | writethrough(可选;writeback 为默认不打印) |
| #core args | 核心参数个数(必须为偶数) |
| core args | 用于调节 core 的 key/value 对,例如 migration_threshold |
| policy name | 策略名称 |
| #policy args | 策略参数个数(必须为偶数) |
| policy args | 策略 key/value 对,例如 sequential_threshold |
| cache metadata mode | ro 表示只读,rw 表示读写 |
关于状态中两个异常指示:
- 若遇到严重到连只读模式都不安全的故障,将不再允许任何 IO,状态输出仅含字符串
Fail,此时应使用用户态恢复工具处理; - 当某次元数据操作失败、导致元数据 superblock 中的
needs_check标志被置位时,状态末尾会出现needs_check,否则为-。出现needs_check时,元数据设备必须先被停用(deactivate)并做检查/修复,cache 才能重新完全正常工作。
内核侧对应实现可见 drivers/md/dm-cache-metadata.c(dm_cache_metadata_set_needs_check / dm_cache_metadata_needs_check)。另外从 status 输出代码还能看到一条辅助信息:cache 特征与版本会以 writethrough=, passthrough=, metadata2= 等形式附加打印(drivers/md/dm-cache-target.c、drivers/md/dm-cache-target.c),在需要诊断缓存模式时可多加留意。
4.3 控制消息(Messages)
不同策略有各自专属的可调参数,dm-cache 用统一的 device-mapper 消息机制读写它们。消息格式为:
<key> <value>
例如:
dmsetup message my_cache 0 sequential_threshold 1024
另一个核心消息是 invalidate_cblocks(缓存块失效)。失效(invalidation)指不写回、直接从缓存中移除一个条目。其格式为:
invalidate_cblocks [<cblock>|<cblock begin>-<cblock end>]*
规则要点:
- 每个 cblock 区间采用**"末端不包含"**(one past the end)语义,例如
5-10表示从 5 到 9 的区间; - 每个 cblock 必须以十进制书写(文档指出,未来可能需要支持十六进制区间变体,以便更高效地对大规模缓存做失效);
- 使用
invalidate_cblocks时缓存必须处于 passthrough 模式——内核对此有显式校验:"%s: cache has to be in passthrough mode for invalidation"(见 drivers/md/dm-cache-target.c)。
示例:
dmsetup message my_cache 0 invalidate_cblocks 2345 3456-4567 5678-6789
这条命令会依次失效 cblock 2345、区间 3456~4566、区间 5678~6788。消息分发入口可见 drivers/md/dm-cache-target.c。
五、内核自带的替换策略:mq / smq / cleaner
策略的编写与实现细节、以及缓存策略消息的完整说明,统一收录于官方配套文档 Documentation/admin-guide/device-mapper/cache-policies.rst。文档同时给出了对策略作者的引导:尽量把事务性(transactionality)排除在策略之外——core 会小心地不去询问任何正在迁移中的块;每个被 target 映射的 bio 都会被交给策略,策略可以简单返回 HIT/MISS,或发起一次迁移;由于是按 bio 而非 request 映射,策略容易被大量小 bio 迷惑,因此 core 会周期性向策略发送 tick,建议策略在每个 tick 内对同一块的统计更新不超过一次。
5.1 multiqueue(mq):已被 smq 取代
mq 策略当前仅是 smq 的别名。其历史调优参数(sequential_threshold、random_threshold、read_promote_adjustment、write_promote_adjustment、discard_promote_adjustment)仍被接受,但不再有任何实际效果。
5.2 Stochastic multiqueue(smq):默认策略
smq 策略是当前的默认策略,核心实现位于 drivers/md/dm-cache-policy-smq.c。它针对 mq 的若干问题做了改进:
- 更低的内存占用:mq 在 64 位机器上每 cache 块约用 88 字节;smq 用 28 位索引而非指针实现数据结构、不保存显式命中计数、用"热点队列"(hotspot queue)取代预缓存(pre-cache,热点条目仅占四分之一槽位),综合下来每 cache 块约 25 字节。
- 层级均衡(level balancing):mq 依据命中计数(约 ln(hit count))把条目放入多层队列的不同层级,导致底层条目过多而失衡;smq 不维护命中计数,而是把命中的条目与上一层最近最少使用(LRU)的条目对调,通过随机过程形成整体顺序,从而可控制每个层级的条目数量,做出更合理的提升/降级决策。
- 强适应性(adaptability):mq 靠命中计数决定提升,新块需超过缓存内最低命中计数,导致工作负载变化时适应很慢;smq 不维护命中计数,并持续跟踪热点队列的表现——热点队列表现不佳时,它会更快地在层级间移动条目,从而迅速适应新的 IO 模式。
用户只需重载使用 cache target 的 DM table,即可从 mq 平滑切换到 smq。副作用有两点:其一,mq 的全部策略提示会被丢弃;其二,在 smq 重新计算 origin 设备上应被缓存的热点之前,缓存性能可能略有下降。
5.3 cleaner:退役专用
cleaner 策略把缓存中所有脏块写回,用于将一块缓存退役(decommission)。它也正是上一节提到的"收缩/退役缓存前清空脏块"的执行者。
六、实战示例:用 dmsetup 创建 dm-cache
原文档给出的权威示例(命令较长时用 \ 续行):
示例 1:writeback 模式 + default 策略
dmsetup create my_cache --table '0 41943040 cache /dev/mapper/metadata \
/dev/mapper/ssd /dev/mapper/origin 512 1 writeback default 0'
解读:
0 41943040:起始扇区 0,总长度 41943040 sectors(即 20GB)的映射区段;cache:target 类型;/dev/mapper/metadata:元数据设备;/dev/mapper/ssd:缓存(快)设备;/dev/mapper/origin:原始(慢)设备;512:块大小 512 sectors(256KB),落在文档推荐的 256KB~1024KB 区间;1:1 个 feature 参数;writeback:写回模式;default:默认策略(当前指向 smq);0:0 个策略参数。
示例 2:writeback 模式 + mq(现为 smq 别名)+ 策略参数
dmsetup create my_cache --table '0 41943040 cache /dev/mapper/metadata \
/dev/mapper/ssd /dev/mapper/origin 1024 1 writeback \
mq 4 sequential_threshold 1024 random_threshold 8'
解读:
- 块大小为 1024 sectors(512KB);
- 策略名为
mq(等价于smq),后面跟着 4 个策略参数:sequential_threshold 1024random_threshold 8
配套文档 cache-policies.rst 中还给出了一个 128GB 规模的等效示例(0 268435456 cache /dev/sdb /dev/sdc /dev/sdd 512 0 mq 4 sequential_threshold 1024 random_threshold 8),可作为大容量场景的参考模板。
把缓存运行中下发策略消息的写法汇总如下:
dmsetup message <mapped device> 0 sequential_threshold 1024
dmsetup message <mapped device> 0 random_threshold 8
dmsetup message my_cache 0 migration_threshold 4096
dmsetup message my_cache 0 invalidate_cblocks 2345 3456-4567 5678-6789
其中 migration_threshold 是 cache target core 直接支持的核心参数(源码注释明确标注该 key 由 core 处理,见 drivers/md/dm-cache-target.c),而 sequential_threshold、random_threshold 等则转发给策略处理。原文档还提到该功能有一组独立的自动化测试套件(device-mapper test suite,由维护者作为独立工程维护),可作为验证行为与回归测试的参考。
七、实操要点速查
- 选择缓存模式:默认 writeback 追求写性能但掉电有丢数据窗口;writethrough 保证数据先落 origin;passthrough 只在缓存内容相干性存疑(如快照回滚后)时用于安全激活与失效重建,进入前缓存必须干净。
- 选择块大小:256KB~1024KB 是文档推荐区间;下限 32KB、上限 1GB,且必须是 64 sectors 的整数倍;块过大浪费缓存、过小放大元数据开销。
- 元数据设备:独立且小;只能被一个 cache 使用;容量超限部分不会被使用;生产环境建议对元数据设备做镜像以增强健壮性。
- 退役/收缩缓存:务必先用 cleaner 策略写回全部脏块;writeback 模式下缩小快设备前不清理会直接导致 resize 失败。
- 显式指定策略:依赖具体策略特性时不要使用
default别名,直接写smq(或已等价的mq)。 - 异常处理:status 中出现
Fail或needs_check时,停止常规 IO 并按文档要求停用元数据设备、做检查修复后再恢复。
八、进一步阅读
- cache-policies.rst:策略编写引导与 mq/smq/cleaner 的完整说明;
- persistent-data.rst:dm-cache 与 thin-provisioning 共用的持久化元数据库;
- 内核实现:drivers/md/dm-cache-target.c(target 主体、构造/状态/消息处理)、drivers/md/dm-cache-metadata.c(元数据与 needs_check 机制)、drivers/md/dm-cache-policy-smq.c(默认 smq 策略实现);
- 同目录下的其他 device-mapper 文档(见 Documentation/admin-guide/device-mapper/index.rst),如 thin-provisioning.rst、writecache.rst,可帮助你理解 dm 栈中不同缓存/精简方案的定位差异。
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
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
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