mir

mir

多平台轻量级JIT编译器框架

MIR是一个轻量级JIT编译器框架,为快速高效的即时编译器实现提供基础。支持x86_64、ARM64、POWER等多种架构,采用强类型中间表示。MIR提供API用于创建模块、函数和指令,支持二进制和文本格式代码处理。编译器使用简化优化流程,包括函数内联和全局公共子表达式消除等,在编译速度和代码性能间取得平衡。MIR适用于需要快速、轻量级JIT编译的项目开发。

MIRJIT编译器中间表示代码优化编译器项目Github开源项目
<p> <a href="https://github.com/vnmakarov/mir/actions?query=workflow%3AAMD64%2DLinux%2DOSX%2DWindows%2Dtest"><img alt="GitHub MIR 测试状态" src="https://yellow-cdn.veclightyear.com/0a4dffa0/2c65c6dd-beae-46c9-8fbe-a35344f69b9e.svg"></a> <a href="https://github.com/vnmakarov/mir/actions?query=workflow%3Aapple%2Daarch64%2Dtest"><img alt="GitHub MIR 在 Apple Silicon 上的测试状态" src="https://yellow-cdn.veclightyear.com/0a4dffa0/c19f3a07-bb46-4d96-a243-c03ced69b80e.svg"></a> <a href="https://github.com/vnmakarov/mir/actions?query=workflow%3Aaarch64%2Dtest"><img alt="GitHub MIR 在 aarch64 上的测试状态" src="https://yellow-cdn.veclightyear.com/0a4dffa0/79f67bb2-8263-44ec-802a-31730023e536.svg"></a> <a href="https://github.com/vnmakarov/mir/actions?query=workflow%3Appc64le%2Dtest"><img alt="GitHub MIR 在 ppc64le 上的测试状态" src="https://yellow-cdn.veclightyear.com/0a4dffa0/cd500c33-f7d1-42d6-9d3f-8cdf9c826408.svg"></a> <a href="https://github.com/vnmakarov/mir/actions?query=workflow%3As390x%2Dtest"><img alt="GitHub MIR 在 s390x 上的测试状态" src="https://yellow-cdn.veclightyear.com/0a4dffa0/acd5703d-252a-410f-859e-646b1362b840.svg"></a> <a href="https://github.com/vnmakarov/mir/actions?query=workflow%3Ariscv64%2Dtest"><img alt="GitHub MIR 在 riscv64 上的测试状态" src="https://yellow-cdn.veclightyear.com/0a4dffa0/0d4dd3cb-f202-4698-b02b-03b0d8670484.svg"></a> <a href="https://github.com/vnmakarov/mir/actions?query=workflow%3AAMD64%2DLinux%2Dbench"><img alt="GitHub MIR 基准测试状态" src="https://yellow-cdn.veclightyear.com/0a4dffa0/33c45113-5566-45bb-843e-ea0413fc3202.svg"></a> </p>

MIR 项目

  • MIR 代表中间内部表示Medium Internal Representation)
  • MIR 项目的目标是为实现快速和轻量级的即时编译器(JIT)提供基础
  • 计划首先尝试在 CRuby 或/和 MRuby 实现中使用 MIR 轻量级 JIT
  • 项目的动机可以在这篇博客文章中找到
  • C2MIR 编译器的描述可以在这篇博客文章中找到
  • MIR 在动态语言 JIT 中代码专门化的未来可以在这篇博客文章中找到

免责声明

  • 除了这里给出的测试和在 x86_64 Linux/OSX、aarch64 Linux/OSX(Apple M1)、ppc64le/s390x/riscv64 Linux 平台上的测试外,绝对不保证代码在任何其他测试或平台上能正常工作

MIR

  • MIR 是强类型的中间表示
  • MIR 可以表示不同架构的 32 位和 64 位机器指令
  • MIR.md 包含了 MIR 及其 API 的详细描述。 以下是 MIR 的简要描述:
  • MIR 由模块组成
    • 每个模块可以包含函数以及一些声明和数据
    • 每个函数都有签名(参数和返回类型)、局部变量(包括函数参数)和指令
      • 每个局部变量都有类型,只能是 64 位整数、浮点数、双精度浮点数或长双精度浮点数, 并且可以绑定到特定的目标机器寄存器
      • 每条指令都有操作码操作数
        • 操作数可以是局部变量(或函数参数)、立即数内存标签引用
          • 立即数操作数可以是 64 位整数、浮点数、双精度浮点数或长双精度浮点数值
          • 内存操作数有类型偏移量基址索引整数局部变量, 以及作为索引比例的整数常量
            • 内存类型可以是 8、16、32 和 64 位有符号或无符号整数类型, 浮点类型、双精度或长双精度浮点类型
              • 使用整数内存值时,首先会通过符号或零扩展将其扩展为 64 位整数值
          • 标签操作数有名称,用于控制流指令
          • 引用操作数用于引用当前模块中的函数和声明,其他 MIR 模块中的函数和声明,或 C 外部函数或声明
        • 操作码描述指令的功能
        • 转换指令用于不同的 32 位和 64 位有符号和无符号值、浮点数、双精度和长双精度浮点值之间的转换
        • 算术指令(加法、减法、乘法、除法、取模)适用于 32 位和 64 位有符号和无符号值、浮点数、双精度和长双精度浮点值
        • 逻辑指令(与、或、异或、不同的移位)适用于 32 位和 64 位有符号和无符号值
        • 比较指令适用于 32 位和 64 位有符号和无符号值、浮点数、双精度和长双精度浮点值
        • 局部变量地址指令用于获取局部变量的地址
        • 分支指令(无条件跳转,以及在零值或非零值上跳转),这些指令将标签作为其中一个操作数
        • 组合比较和分支指令,将标签作为一个操作数,以及两个 32 位和 64 位有符号和无符号值、浮点数、双精度和长双精度浮点值
        • switch 指令,根据作为第一个操作数给出的索引,跳转到作为操作数给出的标签之一
        • 标签地址指令用于获取标签地址,以及无条件间接跳转指令,其操作数包含先前获取的标签地址
        • 函数和过程调用指令
        • 返回指令,可选择返回 32 位和 64 位整数值、浮点数、双精度和长双精度浮点值
        • 专门的轻量级调用和返回指令,可用于在线程解释器和 JIT 编译代码之间快速切换
        • 属性指令,用于在使用惰性基本块版本化时生成专门的机器代码

MIR 示例

  • 您可以通过由创建模块、函数、指令、操作数等函数组成的 API 来创建 MIR
  • 您也可以从 MIR 二进制文本 文件创建 MIR
  • 了解 MIR 的最佳方式是使用 MIR 的文本表示
  • C 语言实现的埃拉托斯特尼筛法示例
#define Size 819000 int sieve (int N) { int64_t i, k, prime, count, n; char flags[Size]; for (n = 0; n < N; n++) { count = 0; for (i = 0; i < Size; i++) flags[i] = 1; for (i = 0; i < Size; i++) if (flags[i]) { prime = i + i + 3; for (k = i + prime; k < Size; k += prime) flags[k] = 0; count++; } } return count; } void ex100 (void) { printf ("sieve (100) = %d\", sieve (100)); }
  • 相同函数的 MIR 文本文件示例:
m_sieve: module export sieve sieve: func i32, i32:N local i64:iter, i64:count, i64:i, i64:k, i64:prime, i64:temp, i64:flags alloca flags, 819000 mov iter, 0 loop: bge fin, iter, N mov count, 0; mov i, 0 loop2: bge fin2, i, 819000 mov u8:(flags, i), 1; add i, i, 1 jmp loop2 fin2: mov i, 0 loop3: bge fin3, i, 819000 beq cont3, u8:(flags,i), 0 add temp, i, i; add prime, temp, 3; add k, i, prime loop4: bge fin4, k, 819000 mov u8:(flags, k), 0; add k, k, prime jmp loop4 fin4: add count, count, 1 cont3: add i, i, 1 jmp loop3 fin3: add iter, iter, 1 jmp loop fin: ret count endfunc endmodule m_ex100: module format: string "sieve (10) = %d\n" p_printf: proto p:fmt, i32:result p_sieve: proto i32, i32:iter export ex100 import sieve, printf ex100: func v, 0 local i64:r call p_sieve, sieve, r, 100 call p_printf, printf, format, r endfunc endmodule
  • func 描述函数的签名(接受一个 32 位有符号整数参数并返回一个 32 位有符号整数值) 和函数参数 N,它将是一个 64 位有符号整数类型的局部变量
    • 函数结果首先由其类型描述,没有名称。 参数总是有名称,并在结果描述之后
    • 函数可能有多个结果,但可能的结果类型数量和组合目前是由机器定义的
  • 如果用 ; 分隔,您可以在一行上写多条指令
  • 指令结果(如果有)总是第一个操作数
  • 我们在计算中使用 64 位指令
  • 我们可以在计算中使用 32 位指令,这在使用 32 位 CPU 时有意义
    • 当我们使用 32 位指令时,我们只取 64 位操作数的 32 位有效部分, 结果的高 32 位部分是由机器定义的(所以如果您编写可移植的 MIR 代码, 请考虑高 32 位部分的值是未定义的)
  • string 以 C 字符串的形式描述数据
    • C 字符串可以直接用作指令操作数。在这种情况下,数据将被添加 到模块中,并使用数据地址作为操作数
  • export 描述在当前模块外可见的模块函数或数据
  • import 描述应在其他 MIR 模块中定义的模块函数或数据
  • proto 描述函数原型。其语法与 func 语法相同
  • call 是用于调用函数的 MIR 指令

运行 MIR 代码

  • 创建 MIR 模块后(通过 MIR API 或读取 MIR 二进制或文本文件), 您应该加载这些模块
    • 加载模块使导出的模块函数和数据可见
    • 您可以使用 MIR_load_external 加载外部 C 函数
  • 加载模块后,您应该链接已加载的模块
    • 链接模块解析导入的模块引用,初始化数据, 并设置调用接口
  • 链接后,您可以解释模块中的函数或调用 由 MIR JIT 编译器(生成器)生成的机器代码。函数可以执行的方式 通常由设置的接口定义。生成代码的方式(在第一次调用时懒惰生成或提前生成) 也可能取决于接口
  • 运行上述示例的代码可能如下所示(这里 m1m2 是模块 m_sievem_e100func 是函数 ex100sieve 是函数 sieve):
/* ctx 是由 MIR_init 创建的上下文 */ MIR_load_module (ctx, m1); MIR_load_module (ctx, m2); MIR_load_external (ctx, "printf", printf); MIR_link (ctx, MIR_set_interp_interface, import_resolver); /* 或使用 MIR_set_gen_interface 生成并使用机器代码 */ /* 或使用 MIR_set_lazy_gen_interface 在函数首次调用时生成代码 */ /* 使用 MIR_gen (ctx, func) 显式生成函数的机器代码 */ MIR_interp (ctx, func, &result, 0); /* 这里的零是参数数量 */ /* 或 ((void (*) (void)) func->addr) (); 通过接口调用解释或生成的代码 */

在 Linux 上通过 binfmt_misc 运行二进制 MIR 文件

mir-bin-run 二进制文件准备用于 binfmt_misc,使用以下行(示例):

line=:mir:M::MIR::/usr/local/bin/mir-bin-run:P echo $line > /proc/sys/fs/binfmt_misc/register

请根据您的系统调整 mir-bin-run 二进制文件的路径,上面是默认路径

然后运行

c2m your-file.c -o your-file chmod +x your-file ./your-file your args

可执行文件可通过环境变量"配置":

  • MIR_TYPE 设置代码执行的接口:interp(用于解释), jit(用于生成)和 lazy(用于懒惰生成,默认);
  • MIR_LIBS(冒号分隔列表)定义要加载的额外库列表;
  • MIR_LIB_DIRSLD_LIBRARY_PATH(冒号分隔列表)定义一个额外的 目录列表,用于搜索库。

由于mir-bin-runbinfmt_misc紧密相关,直接调用mir-bin-run可能会有些奇怪。 binfmt_misc上的P标志会传递一个额外的参数,包含MIR二进制文件的完整路径。

MIR项目的当前状态

当前MIR

  • 你可以使用C语言的setjmp/longjmp函数在MIR中实现longjump
  • 二进制MIR代码通常比相应的MIR文本代码小10倍,读取速度快10倍
  • MIR解释器的速度比MIR JIT编译器生成的代码慢约6-10倍
  • LLVM IR到MIR的转换器尚未完成,可能永远不会完全实现,因为LLVM IR比MIR更丰富,但将标准C/C++生成的LLVM IR转换为MIR是可行的任务

MIR项目的可能未来状态

未来MIR

  • WASM到MIR的转换应该相当直接
    • 只需为MIR提供一个小型WASM运行时,用于WASM浮点数舍入指令
  • 将GCC移植到MIR也是可能的。有经验的GCC开发者可以在6到12个月内完成此工作
  • 据我估计,将MIR JIT编译器移植到mips64或sparc64每个目标平台需要1-2个月的工作
  • 为了性能考虑,将MIR JIT编译器移植到32位目标平台需要实施额外的小型分析过程,以获取哪些64位变量仅在32位指令中使用的信息

MIR JIT编译器

  • 非常短的优化流程,以保证速度和轻量级

  • 仅使用最有价值的优化:

    • 函数内联
    • 全局公共子表达式消除
    • 变量重命名
    • 寄存器压力敏感的循环不变代码移动
    • 条件常量传播
    • 死代码消除
    • 代码选择
    • 快速寄存器分配器,具有
      • 积极的寄存器和栈槽位合并以消除复制
      • 生存期分割
  • 不同的优化级别,以调整编译速度和生成代码性能

  • 在寄存器分配之前使用MIR的SSA形式

    • 我们使用Braun算法的一种形式来构建SSA(M. Braun等人的"简单高效的静态单赋值形式构建")
  • 优化实现的简单性优先于极致的生成代码性能

  • 关于完整JIT编译器流程的更多细节: MIR生成器

  • 简化:降低MIR

  • 内联:内联MIR调用

  • 构建CFG:构建控制流图(基本块和CFG边)

  • 构建SSA:通过向操作数添加phi节点和SSA边来构建静态单赋值形式

  • 地址转换:移除或更改MIR ADDR指令

  • 全局值编号:通过GVN移除冗余指令。这包括常量传播和冗余加载消除

  • 复制传播:SSA复制传播和移除冗余扩展指令

  • 死存储消除:移除冗余存储

  • 死代码消除:移除未使用输出的指令

  • 压力缓解:移动指令以减少寄存器压力

  • SSA合并:合并地址以及比较和分支指令对

  • SSA转出:移除phi节点和SSA边

  • 跳转优化:各种跳转优化

  • 机器化:运行机器相关代码,为调用ABI、2操作数指令等转换MIR

  • 查找循环:查找自然循环并构建循环树

  • 构建活跃信息:计算基本块的活跃入口和活跃出口

  • 构建寄存器冲突:为移动中涉及的寄存器构建冲突矩阵。用于寄存器合并

  • 合并:积极的寄存器合并

  • 寄存器分配器(RA):基于优先级的线性扫描RA,具有生存期分割

  • 构建生存期范围:计算寄存器的程序点范围

  • 分配-O0使用快速RA,-O1及以上使用基于优先级的线性扫描RA

  • 重写:根据分配使用保留的硬寄存器转换MIR

  • 合并(代码选择):将数据相关指令合并为一条

  • 死代码消除:移除未使用输出的指令

  • 生成机器指令:运行机器相关代码创建机器指令

C到MIR的转换

  • 我们实现了一个小型C11(2011 ANSI C标准,带有一些GCC扩展)到MIR的编译器c2m。 参见README.md
  • 除MIR外,C代码也可以作为JIT编译器的输入
    • 使用C作为JIT编译器的输入可能会使编译速度降低至多2倍

项目代码结构

  • 文件mir.hmir.c包含主要的API代码,包括MIR二进制和MIR文本表示的输入/输出
  • 文件mir-dlist.hmir-mp.hmir-varr.hmir-bitmap.hmir-hash.hmir-htab.hmir-reduce.h分别包含双向链表、内存池、可变长数组、位图、哈希计算、哈希表和数据压缩/解压缩的通用代码。文件mir-hash.h是一个通用、简单、高质量的哈希函数,供哈希表使用
  • 文件mir-interp.c包含MIR代码解释执行的代码。它被包含在mir.c中,从不单独编译
  • 文件mir-gen.hmir-gen.cmir-gen-x86_64.cmir-gen-aarch64.cmir-gen-ppc64.cmir-gen-s390x.cmir-gen-riscv64.c包含MIR JIT编译器的代码
    • 文件mir-gen-x86_64.cmir-gen-aarch64.cmir-gen-ppc64.cmir-gen-s390x.cmir-gen-riscv64.c是JIT编译器的机器相关代码
  • 文件mir-<target>.c包含解释器和JIT编译器共用的简单机器相关代码
  • 文件mir-<target>.h包含解释器和JIT编译器共用的声明
  • 文件mir2c/mir2c.hmir2c/mir2c.c包含MIR到C编译器的代码。生成的代码可能不具有可移植性
  • 文件c2mir/c2mir.hc2mir/c2mir.cc2mir/c2mir-driver.cc2mir/mirc.h包含C到MIR编译器的代码。目录c2mir/x86_64c2mir/aarch64c2mir/ppc64c2mir/s390xc2mir/riscv64中的文件分别包含C到MIR编译器的x86_64、aarch64、ppc64le、s390x和riscv机器相关代码
  • 文件mir-bin-run.c包含上述描述的mir-bin-run的代码
  • 文件mir-bin-driver.cb2ctab工具可用于以可移植的方式从MIR二进制文件生成二进制文件
  • 目录mir-utils包含用于处理MIR的各种工具,例如将二进制MIR转换为文本MIR,反之亦然
  • 目录adt-testsmir-testsc-testsc-benchmarks包含用于测试和基准测试MIR和c2m的代码

使用当前MIR项目代码

  • 您可以通过make benchmake test运行一些基准测试和测试

当前MIR性能数据

  • 在搭载64GB内存的Intel i5-13600K上,运行FC37和GCC-12.3.1

    MIR生成器MIR解释器gcc -O2gcc -O0
    编译[1]1.0 (249us)0.09 (22us)109 (27.1ms)105 (26.1ms)
    执行[2]1.0 (1.74s)13.7 (23.8s)0.92 (1.6s)2.28 (3.97s)
    代码大小[3]1.0 (557KB)0.43 (240KB)58 (32.2MB)58 (32.2MB)
    代码行数[4]1.0 (23.4K)0.48 (11.3K)103 (2420K)103 (2402K)

[1] 基于C筛选代码的编译耗时(不包含任何头文件,并为GCC使用内存文件系统),以及MIR解释器和MIR生成器(优化级别2)编译相应MIR筛选代码的耗时

[2] 基于使用MIR生成器优化级别2的10次运行中的最佳耗时

[3] 基于GCC的cc1和MIR核心及解释器或生成器的精简大小

[4] 我的估计仅基于x86-64 GNU C编译器所需的文件和用于创建和运行MIR代码的最小程序的MIR文件

当前C2MIR性能数据

  • 在搭载64GB内存的Intel i5-13600K上,运行FC37和GCC-12.3.1

    c2m -O2 -eg(生成器)c2m -ei(解释器)gcc -O2gcc -O0
    编译[1]1.0 (336us)1.0 (337us)80 (27.1ms)77 (26.1ms)
    执行[2]1.0 (1.74s)13.7 (23.8s)0.92 (1.6s)2.28 (3.97s)
    代码大小[3]1.0 (961KB)1.0 (961KB)34 (32.2MB)34 (32.2MB)
    代码行数[4]1.0 (54.8K)1.0 (54.8K)44 (2420K)44 (2420K)

[1] 基于C筛选代码的编译耗时(不包含任何头文件,并为GCC使用内存文件系统)

[2] 基于使用MIR生成器优化级别2的10次运行中的最佳耗时

[3] 基于GCC的cc1和C2MIR、MIR核心、解释器和生成器的精简大小

[4] 基于所有源文件,不包括测试

  • 以下是不同C编译器在15个小型C基准测试(来自c-benchmarks目录)中与GCC -O2相关的生成代码性能,测试在同一台机器上进行,其中:
    • gcc版本为12.3.1
    • clang版本为15.0.7
    • chibicc是Rui Ueyama的最新C11实现
    • cparser是基于相当复杂的后端libFirm(版本1.22)的C99实现
    • cproc是Michael Forney基于QBE编译器后端的C11实现
    • lacc是C89实现
    • pcc(1.2.0.DEVEL)是便携式C编译器的现代版本
    • tcc(0.9.27)是微型C11编译器
    • emcc(2.0.20)是使用wasmer(1.0.2)运行时的Emscripten编译器,用于WebAssembly
    • wasi cranelift是基于cranelift后端的C到WebAssembly的clang编译器(11.0.0),使用wasmer(1.0.2)
    • wasi LLVM是基于LLVM后端的C到WebAssembly的clang编译器(11.0.0),使用wasmer(1.0.2)
    • wasi singlepass是基于singlepass后端的C到WebAssembly的clang编译器(11.0.0),使用wasmer(1.0.2)
    • wasi wasmtime是基于cranelift后端的C到WebAssembly的clang编译器(11.0.0),使用wasmtime(0.26.0)运行时
平均值几何平均值
gcc -O21.001.00
gcc -O00.630.57
c2m -eg0.960.91
c2m -eb0.920.85
chibicc0.380.30
clang -O21.121.09
cparser -O31.020.98
cproc0.680.65
lacc -O30.470.39
pcc -O0.800.78
tcc0.540.50
emcc -O2/wasmer0.600.55
wasi -O2/wasmer cranelift0.600.54
wasi -O2/wasmer LLVM0.780.72
wasi -O2/wasmer singlepass0.450.36
wasi -O2/wasmtime0.920.87

MIR项目的竞争对手

  • 我只看到三个项目可以被视为或改编为真正的通用轻量级JIT竞争对手
  • QBE:
    • 体积小(10K行C代码)
    • 使用基于SSA的IR(类似简化版的LLVM IR)
    • 具有与MIR生成器相同的优化,外加别名分析,但QBE没有内联
    • 生成汇编代码,使QBE在机器代码生成速度上比MIR生成器慢30倍
    • 在我的基准测试中,它生成的代码性能几何平均值仅为GCC -O2的65% (MIR生成的代码性能为GCC -O2的91%),同时编译速度与MIR相当
  • LIBJIT 起源于DotGNU项目:
    • LIBJIT规模较大:
      • 80K行C代码(不包括动态Pascal编译器),而MIR只有20K行C代码 (不包括C到MIR编译器)
    • LIBJIT的优化较少:只有复制传播和寄存器分配
  • RyuJIT 是.NET Core运行时的一部分:
    • RyuJIT规模更大:360K SLOC
    • RyuJIT的优化基本上是MIR生成器的优化
    • RyuJIT使用SSA
  • 其他候选项:
    • LIBFirm:独立性较差、规模大(140K LOC)、使用SSA、 生成汇编代码、使用LGPL2许可
    • CraneLift:独立性较差、 规模大(70K行Rust代码)、使用SSA、Apache许可
    • NanoJIT,独立性好、中等规模(40K行C++代码)、仅简单RA、 Mozilla公共许可证

移植MIR

  • 目前MIR可在x86_64、aarch64、ppc64le、s390x、riscv64 Linux和x86_64/aarch64(Apple M1)MacOS上运行
  • HOW-TO-PORT-MIR.md概述了移植MIR的过程
    • 据我估计,一个经验丰富的开发者可以在1-2个月内将MIR(包括c2m)移植到另一个目标平台

编辑推荐精选

TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

热门AI工具生产力协作转型TraeAI IDE
蛙蛙写作

蛙蛙写作

AI小说写作助手,一站式润色、改写、扩写

蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。

AI助手AI工具AI写作工具AI辅助写作蛙蛙写作学术助手办公助手营销助手
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

聊天机器人AI助手热门AI工具AI对话
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

热门AI工具AI办公办公工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

模型训练热门AI工具内容创作智能问答AI开发讯飞星火大模型多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

AI助手热门AI工具AI创作AI辅助写作讯飞绘文内容运营个性化文章多平台分发
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

下拉加载更多