GLSLNodeBuilder:three.js WebGL2 后端中面向 GLSL 的节点着色器生成器
GLSLNodeBuilder 是 three.js 节点着色器体系(Node / TSL)中面向 GLSL 的代码生成器(NodeBuilder)。它的职责是把 NodeMaterial、计算节点等抽象出来的“节点数据流”翻译成可直接交给 WebGL2 编译执行的 GLSL ES 3.0 着色器源码,并同时产出纹理采样器、Uniform Buffer、Vertex Buffer 等绑定元数据,供渲染器创建渲染/计算管线使用。读完本文,你将完整掌握它的继承关系、四类核心数据结构、buildCode() 主流程、全部纹理采样代码生成方法、uniform 与内置变量的 GLSL 映射规则,以及它在 WebGL 回退后端中如何用 PBO/Transform Feedback 补齐 WebGL2 的能力缺口。
1. 它在 three.js 渲染架构中的位置
GLSLNodeBuilder 的类注释清晰地定义了它的定位:
A node builder targeting GLSL. This module generates GLSL shader code from node materials and also generates the respective bindings and vertex buffer definitions. These data are later used by the renderer to create render and compute pipelines for render objects.
从源码结构可以确认它属于「webgl-fallback」渲染后端。在 WebGLBackend.js 中,createNodeBuilder() 直接返回 new GLSLNodeBuilder( object, renderer ),也就是说:当渲染器需要回退到 WebGL2 环境执行节点着色器时,最终都会由 GLSLNodeBuilder 来产出 #version 300 es 的 GLSL 代码。
其继承关系与协作对象如下:
- 继承自 NodeBuilder(所有后端代码生成器的抽象基类),并通过
super( object, renderer, new GLSLNodeParser() )注入 GLSL 专用的解析器。 - GLSLNodeParser 负责把一段 GLSL 函数源码解析成
GLSLNodeFunction,从而支持“用 GLSL 书写并复用的函数节点”。 - 生成的 uniform/绑定对象(
NodeSampledTexture、NodeUniformsGroup、NodeUniformBuffer等)位于 src/renderers/common/nodes/,被后端渲染器用来装配绑定组与布局。
同一套节点材质在 WebGPU 后端对应的是 TSLNodeBuilder 相关实现 一类的生成器;GLSLNodeBuilder 则是把抽象节点系统落地到 GLSL 方言的关键一环。如果想先了解节点系统的上层概念,可参考 docs/TSL.md。
2. 构造函数与参数
new GLSLNodeBuilder( object : Object3D, renderer : Renderer )
| 参数 | 类型 | 说明 |
|---|---|---|
object |
Object3D |
要生成着色器的三维对象(渲染对象或计算对象) |
renderer |
Renderer |
当前渲染器实例,用于访问后端、扩展等上下文 |
构造函数(对应源码 GLSLNodeBuilder.js 第 178-220 行)除了调用父类构造函数外,还会初始化四份关键数据。注意类注释中把本类标注为 @augments NodeBuilder,即它属于 NodeBuilder 子类,父类中已维护 uniforms、varyings、attributes、flowNodes 等跨后端公共状态。
3. 四个核心属性(生成器的“工作台账”)
3.1 .builtins : Object.<string, Array.<string>>
每个 shader stage('vertex'、'fragment'、'compute')使用过的 builtin 声明的数组。
this.builtins = { vertex: [], fragment: [], compute: [] };
例如 enableHardwareClipping() 会向 builtins['vertex'] 中推入 out float gl_ClipDistance[ N ],enableMultiview() 会推入 layout(num_views = 2) in。
3.2 .extensions : Object.<string, Map.<string, Object>>
每个 shader stage 使用过的扩展集合,key 为扩展名,value 为 { name, behavior } 对象。enableExtension() 负责写入,getExtensions() 负责把它序列化为 #extension name : behavior 指令。
3.3 .transforms : Array.<Object.<string, (AttributeNode|string)>>
与 Transform Feedback(WebGL2 中用于模拟 compute 结果回读的手段)相关的数组,元素形如 { varyingName, attributeNode },由 registerTransform() 追加、getTransforms() 消费。
3.4 .uniformGroups : Object.<string, Object.<string, NodeUniformsGroup>>
API 文档对该属性的描述是:按 shader stage('vertex'/'fragment'/'compute')再按 group('render'/'frame'/'object')两层字典来管理 UBO。从当前实现看,uniformGroups 在代码中实际以 group 名(如 render/frame/object)作为 key 存储共享的 NodeUniformsGroup 实例,各 stage 通过 getBindGroupArray() 分别引用这些组(参见 getUniformFromNode 的实现),并在生成 uniform 文本时以“std140 布局的 uniform block”统一输出。理解其意图即可:它把散落的 uniform 按生命周期归组,使渲染器可以跨 stage 共享同一份 UBO。
4. 主流程 buildCode():组装完整 GLSL 着色器
4.1 阶段数据收集
buildCode()(源码 第 1659 行)是控制各 shader stage 代码构建的入口。它覆盖 NodeBuilder#buildCode:
const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} };
- 材质非空(NodeMaterial):产出
vertex+fragment两段; - 材质为空:视为纯计算对象,只产出
compute一段。
随后每个 stage 依次收集:
stageData.extensions = this.getExtensions( shaderStage );
stageData.uniforms = this.getUniforms( shaderStage );
stageData.attributes = this.getAttributes( shaderStage );
stageData.varyings = this.getVaryings( shaderStage );
stageData.vars = this.getVars( shaderStage, true );
stageData.structs = this.getStructs( shaderStage );
stageData.codes = this.getCodes( shaderStage );
stageData.transforms = this.getTransforms( shaderStage );
stageData.flow = flow;
flow 是由 flowNodes(节点按执行顺序形成的流图)拼装出来的主逻辑:每个节点一段缩进代码,遇到主节点时——vertex stage 会写 gl_Position = ...,fragment stage 会写 fragColor = ...(除非使用显式的输出 struct)。此外 buildCode() 还会在 BatchedMesh 但设备不支持 WEBGL_multi_draw 时自动补充 uniform uint nodeUniformDrawId; 作为回退(与 getDrawIndex() 返回的 nodeUniformDrawId 对应)。
4.2 GLSL ES 3.0 输出模板
拼装完成后的 stageData 被交给两个私有模板方法:
_getGLSLVertexCode()(源码第 1567 行):顶点着色器模板,顺序为#version 300 es→ 签名注释 → extensions → 默认精度 → structs → uniforms → varyings → attributes → vars → codes →main(),main 中先执行 transforms 再执行 flow,最后固定gl_Position = ...与gl_PointSize = 1.0。_getGLSLFragmentCode()(源码第 1619 行):片元着色器模板,不包含 attributes,以 flow 收尾。
关键说明:
- 所有 shader 都强制声明默认精度
precision highp ...(float/int 及各类 sampler 全集,见源码defaultPrecisions,第 121-142 行)。 - compute 阶段复用顶点模板(
computeShader = this._getGLSLVertexCode(...)),因为 WebGL2 后端用顶点着色器 + Transform Feedback 来模拟计算管线,gl_Position在 compute 分支不会被写入。 - 每段代码段上方都保留
// extensions、// structs等注释,方便开发者直接查看最终着色器排查问题。
4.3 buildFunctionCode( shaderNode ) : string
覆盖 NodeBuilder#buildFunctionCode。它把某个 ShaderNodeInternal(例如由 GLSLNodeParser 解析出来的 GLSL 函数节点)编译成一段独立的 GLSL 函数:
返回类型 函数名( 参数类型 参数名, ... ) {
局部变量声明...
函数体流程
return 结果;
}
函数签名来自节点 layout 的输入输出类型映射,参数类型通过 this.getType() 转换成 GLSL 类型名。该机制让“JS 里用字符串写 GLSL 函数”与节点系统无缝衔接。
5. 纹理采样代码生成方法族(核心输出)
这是 GLSLNodeBuilder 最密集的功能区:把抽象纹理节点翻译成具体的 GLSL 采样/读取内建函数。以下方法的完整实现在 GLSLNodeBuilder.js 第 576-851 行,公共参数含义如下:
texture:纹理对象,用于判断深度纹理、立方体、数组纹理等形态;textureProperty:shader 中纹理 uniform 的名称;uvSnippet/depthSnippet/offsetSnippet:纹理坐标、0 起始的数组层索引、纹素偏移的 GLSL 片段;- 各方法专属的
bias/level/grad/compare/gather/flipY片段:mip 偏置、显式 mip 层、显式梯度、深度比较参考值、采集通道、是否翻转 Y。
5.1 各方法 → GLSL 内建函数对照
| 方法 | 用途 | 生成的 GLSL(示意) |
|---|---|---|
.generateTexture() |
常规采样/读取 | texture(map, uv) / textureOffset(map, uv, off);深度纹理取 .x |
.generateTextureBias() |
带 mip 偏置采样 | texture(map, uv, bias) / textureOffset(map, uv, off, bias) |
.generateTextureLevel() |
显式 mip 层采样 | textureLod(map, uv, level) / textureLodOffset(...) |
.generateTextureGrad() |
显式梯度采样 | textureGrad(map, uv, dPdx, dPdy) / textureGradOffset(...) |
.generateTextureLoad() |
不滤波的单纹素读取 | texelFetch(map, ivec, level) / texelFetchOffset(...) |
.generateTextureCompare() |
阴影深度纹理比较采样 | fragment 阶段:texture(sampler2DShadow, vec3(uv, ref)) 等;其他阶段直接报错 |
.generateTextureGather() |
一次取 4 个相邻纹素 | 内部 polyfill:tsl_textureGather(...) |
.generateTextureGatherCompare() |
4 纹素上的深度比较 | 内部 polyfill:tsl_textureGatherCompare(...) |
关键实现细节:
- 深度纹理约定:凡
texture.isDepthTexture === true,采样结果都要追加.x;比较采样只在'fragment'stage 允许,否则抛出WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${stage} shader.(源码 第 781 行)。 - 立方体贴图阴影:比较采样对 CubeTexture 使用
texture(map, vec4(方向, 参考值));数组纹理则拼成vec4(uv, depth, ref)。 - WebGL2 没有原生
textureGather:因此该族方法通过_include()注入 GLSL polyfill 函数,如tsl_textureGather(见源码第 15-29 行的glslPolyfills),它用四次textureLod手动重建 2×2 纹素结果,并依据flipY处理 Y 轴翻转(WebGL 纹理方向约定,isFlipY()恒为true)。 - 显式 mip 层采样时若传入
depthSnippet,UV 会被包装成vec3(uv, depth),从而把 2D 数组纹理映射到正确语法。 .generateTextureLoad()对 storage buffer 的 PBO 读取也复用:见下文第 8 节。
5.2 采样器类型的自动推导(getUniforms)
getUniforms()(第 859 行)根据 uniform 的类型与纹理形态生成对应 sampler 声明:
| 场景 | 生成的 GLSL 声明 |
|---|---|
| 普通纹理 | uniform sampler2D name; |
| 3D 纹理(非数组) | uniform sampler3D name; |
| 数组纹理(含 DataArray/压缩数组) | uniform sampler2DArray name; |
带 compareFunction 且按比较采样 |
uniform sampler2DShadow / sampler2DArrayShadow; |
| 立方体贴图 / 深度立方体贴图 | uniform samplerCube / samplerCubeShadow; |
整数数据纹理(IntType/UnsignedIntType) |
前缀 i / u(如 usampler2D) |
| Buffer uniform | 具名块:bufferName { type name[count]; }; |
| 归组 uniform(render/frame/object 组) | layout( std140 ) uniform 组名 { ... }; |
普通 uniform 会补上 uniform 关键字;节点上设置了 precision(low/medium/high)时,会用 precisionLib({ low:'lowp', medium:'mediump', high:'highp' })映射为 GLSL 精度限定符拼在类型前。归组 uniform 通过 _getGLSLUniformStruct() 统一输出为 std140 布局的 uniform block,保证跨 stage 的字节布局一致。
6. 顶点输入、varying、struct 的输出
6.1 .getAttributes( shaderStage ) : string
vertex/compute 阶段把属性数组逐条序列化为带绑定位置的顶点输入:
layout( location = 0 ) in vec3 position;
layout( location = 1 ) in vec2 uv;
compute 阶段同样会写 in 属性(因为 WebGL 回退把计算放到顶点阶段执行,几何数据来自绑定的顶点缓冲)。
6.2 .getVaryings( shaderStage ) : string
- vertex/compute 写
out,fragment 写in; - 需要插值的 varying 依据
interpolationTypeMap映射(perspective → smooth、linear → noperspective),必要时附加centroid; - 整型类 varying(类型含
int/uv/iv)自动加flat限定符,避免逐像素插值; - 不需要插值的 varying 在 vertex 阶段生成同名局部变量;
- 最后把
this.builtins[stage]中的内置声明原样拼接(第 1220-1224 行)。
6.3 .getStructs( shaderStage ) 与 .getStructMembers( struct )
非输出 struct 被序列化为标准 struct 名 { 成员类型 成员名; ... };;带 output 标记的 struct 成员则转成 layout( location = N ) out ... 的多渲染目标输出。fragment 阶段若最终没有显式输出 struct,会自动补一句:
layout( location = 0 ) out <输出类型> fragColor;
.getOutputStructName() 对本类返回空字符串(注释明确写着 “Not relevant for GLSL”,即 GLSL 不需要 struct 命名的输出封装——而 WebGPU 端需要)。
6.4 .getTypeFromAttribute( attribute ) : string
把 BufferAttribute 映射为 GLSL 类型。它对整型属性做了 WebGL2 特有的纠正:GLSL ES 3.0 中非高精度整型顶点属性默认是浮点解释,因此只有当底层数组确实是 Uint32Array/Int32Array 时才保留 i/u 前缀,否则去掉前缀以匹配实际数据(源码 第 1028-1049 行)。
7. uniform 与 binding 的生成
7.1 .getUniformFromNode( node, type, shaderStage, name = null ) : NodeUniform
文档称其为“最重要的方法之一”:为给定 uniform 节点生成匹配的绑定实例。源码实现(第 1766 行起)根据 type 分发创建不同绑定对象并压入对应绑定组:
| type | 创建/获取的绑定实例 | 说明 |
|---|---|---|
texture |
NodeSampledTexture |
2D 采样纹理绑定 |
cubeTexture / cubeDepthTexture |
NodeSampledCubeTexture |
立方体纹理绑定 |
texture3D |
NodeSampledTexture3D |
3D 纹理绑定 |
buffer |
NodeUniformBuffer |
具名 buffer 绑定,名称自动改写为 buffer${ node.id } |
| 其余标量/向量 | NodeUniformsGroup + getNodeUniform() |
归入组,按名称去重,避免跨 stage 重复添加 |
创建结果缓存在 nodeData 的 uniformGPU 上,同一节点不会被重复生成绑定。这些绑定对象随后被 renderer 用于创建绑定组(bind groups)与布局,因此 GLSLNodeBuilder 输出的不只是字符串,还有运行期真正需要的资源元数据。
7.2 .getPropertyName( node, shaderStage ) : string
非纹理/非 buffer 的 NodeUniform 直接返回其名称;其余走父类 super.getPropertyName()(保持与既有 NodeBuilder 一致的命名缓存逻辑)。
8. storage buffer 的 PBO 回退方案
WebGL2 无法像 WebGPU 那样把 storage buffer 直接暴露给片元/顶点着色器(supports.storageBuffer 在本类中为 false,见源码第 107-110 行)。GLSLNodeBuilder 采用的替代方案是 Pixel Buffer Object(PBO),把 storage buffer 的数据重新包装成一张纹理,用“采纹素”代替“读 buffer”:
.setupPBO( storageBufferNode )(第 377 行):把属性数组按itemSize与数据类型映射成合适像素格式(如RGBAIntegerFormat+UnsignedIntType),并扩充到近似正方形的宽高(width取 2 的幂),构造一张DataTexture(标记isPBOTexture = true),最终通过getUniformFromNode()注册为纹理 uniform。.generatePBO( storageArrayElementNode ) : string(第 483 行):把“storage 数组的某个元素”的读写翻译成 PBO 纹理的texelFetch访问:用textureSize(...)取宽度,把线性索引拆成ivec2( index % width, index / width ),按itemSize截取对应通道,返回可作为变量使用的属性名。
像素格式的推断来自常量表(src/constants.js 中的 RedFormat/RGFormat/RGBFormat/RGBAFormat 及其整型变体、FloatType 等)。若你在代码里对 storage buffer 做 attribute.array 之类的假设,注意此路径会替换为扩容后的数组并附加 pbo/pboNode 元数据。
9. 内置变量(builtins)的 GLSL 映射
这组 getter 把节点系统里抽象的内置量映射为 GLSL 内建变量:
| 方法 | 返回的 GLSL | 备注 |
|---|---|---|
.getVertexIndex() |
uint( gl_VertexID ) |
覆盖父类 |
.getInstanceIndex() |
uint( gl_InstanceID ) |
覆盖父类;compute 语境下代表“在工作组网格内线性化的调用索引” |
.getInvocationLocalIndex() |
uint( gl_InstanceID ) % workgroupSize |
由对象的 workgroupSize 计算 |
.getDrawIndex() |
uint( gl_DrawID ) 或 nodeUniformDrawId |
设备支持 WEBGL_multi_draw 时用前者,否则回退为 uniform(配合 buildCode() 注入的兜底声明) |
.getFrontFacing() |
gl_FrontFacing |
覆盖父类 |
.getFragCoord() |
gl_FragCoord.xy |
覆盖父类 |
.getFragDepth() |
gl_FragDepth |
— |
.getClipDistance() |
gl_ClipDistance |
需要 WEBGL_clip_cull_distance 支持 |
.getSubgroupSize() / .getInvocationSubgroupIndex() / .getSubgroupIndex() |
抛错 | WebGL 后端不支持 subgroup,报错信息明确提示 |
.getOutputStructName() |
'' |
GLSL 无输出 struct 概念 |
注意 .getInvocationLocalIndex() 依赖 this.object.workgroupSize,只有计算节点配置了工作组尺寸才有意义。
10. 方法名解析、类型转换与能力探测
10.1 .getMethod( method ) 与 GLSL 方法映射表
节点系统里很多操作以通用名字出现,GLSLNodeBuilder 通过 glslMethods 表(源码第 81-99 行)解析为 GLSL 内建函数名:
equals → equal- 位转换:
bitcast_float_int → floatBitsToInt、bitcast_int_float → intBitsToFloat、bitcast_float_uint → floatBitsToUint、bitcast_uint_float → uintBitsToFloat,而uint↔int两种方向因 GLSL 无直接内建,映射到自定义 polyfilltsl_bitcast_uint_to_int/tsl_bitcast_int_to_uint; - 打包:
floatpack_snorm_2x16 → packSnorm2x16、floatpack_unorm_2x16 → packUnorm2x16、floatpack_float16_2x16 → packHalf2x16、floatpack_snorm_4x8 → tsl_packSnorm4x8(4×8 无原生函数,走 polyfill); - 解包:
unpackSnorm2x16 / unpackUnorm2x16 / unpackHalf2x16以及 4×8 的 polyfill。
.getBitcastMethod( type, inputType ) 把 bitcast_${inputType}_${type} 交给 getMethod() 解析;.getFloatPackingMethod( encoding, layout = '2x16' ) 与 .getFloatUnpackingMethod( ... ) 同理,生成 floatpack_${encoding}_${layout} / floatunpack_... 的方法名。需要 polyfill 时 _include() 会先把对应的 CodeNode 构建并注入代码段头部。
10.2 .getTernary( condSnippet, ifSnippet, elseSnippet )
把通用三元操作直接生成为 GLSL 原生写法:条件 ? 分支A : 分支B。
10.3 能力探测 .isAvailable( name ) : boolean
先查静态表 supports,默认只有两项:swizzleAssign: true(GLSL 支持向量分量写回)、storageBuffer: false。未知能力则通过 WebGL 扩展探测,结果带缓存:
float32Filterable→OES_texture_float_linearclipDistance→WEBGL_clip_cull_distance
10.4 .isFlipY() 与 .needsToWorkingColorSpace( texture )
.isFlipY()恒返回true:GLSL/WebGL 语境下纹理数据统一按 Y 轴翻转约定处理(覆盖父类)。.needsToWorkingColorSpace()只在视频纹理且 colorSpace 非NoColorSpace时返回true,表示需要在着色器端手动做工作色彩空间转换。
10.5 保留字保护
类内还维护了一份庞大的 glslReservedKeywords(关键字、未来保留字、类型名,甚至 main),用于在生成变量名时避开 GLSL 保留字,保证输出代码可编译。
11. 扩展开关:硬裁剪、多视图与 Transform Feedback
11.1 .enableExtension( name, behavior, shaderStage = this.shaderStage )
按 stage 写入扩展表;.getExtensions( shaderStage ) 负责输出形如 #extension GL_ANGLE_multi_draw : require 的指令(BatchedMesh 且支持 WEBGL_multi_draw 时 vertex 阶段会被自动 enable)。
11.2 .enableHardwareClipping( planeCount )
启用 GL_ANGLE_clip_cull_distance 并在 vertex 内建中加入 out float gl_ClipDistance[ planeCount ],用 GPU 硬件做剪裁平面剔除(相比软件裁剪更高效)。
11.3 .enableMultiview()
面向 XR/多视图渲染:在 fragment 与 vertex 两阶段同时启用 GL_OVR_multiview2,并在 vertex 内建中加入 layout(num_views = 2) in。
11.4 Transform Feedback:.registerTransform() / .getTransforms( shaderStage )
.registerTransform( varyingName, attributeNode )把{ varyingName, attributeNode }追加到this.transforms;.getTransforms()遍历该数组,为每个有属性名的注册项生成赋值语句varyingName = attributeName;插到main()的开头。
这正对应 compute 回退链路:WebGL2 后端把计算当作一次“顶点处理 + 结果捕获”的过程,捕获哪些数据由注册的 varying 决定,捕获结果随后作为 attributes/vertex buffer 定义回传给渲染器——呼应了类的总述中“generates the respective bindings and vertex buffer definitions”一句。
12. 总结:如何阅读与调试
GLSLNodeBuilder 位于 src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js,共约 1860 行,是 three.js 节点体系在 WebGL2 上的“最后一公里”编译器。通读时建议按四层理解:
- 数据层:
builtins、extensions、transforms、uniformGroups四张表记录“用过哪些东西”; - 装配层:
buildCode()调用getAttributes/getUniforms/getVaryings/getStructs/getExtensions/getTransforms等 getter,把各 stage 的文本片段填入 GLSL ES 3.0 模板; - 语义层:
generateTexture*一族负责纹理采样语法,getUniformFromNode一族负责把 uniform 节点变成渲染器可用的绑定实例; - 回退层:PBO 纹理模拟 storage buffer、Transform Feedback 模拟 compute、polyfill 补全
textureGather与 4×8 打包/位转换等 WebGL2 缺失能力。
若你需要在 WebGL2 下排查节点材质的着色器问题,可以直接把 WebGLBackend 生成的 vertexShader/fragmentShader 文本打印出来对照上面的模板注释段(// extensions、// structs、// flow 等)逐段定位。相关后续阅读:NodeBuilder 基类文档、docs/TSL.md。
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 StartedRust0624
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