CPython C API 中的公共对象结构:PyObject、PyMethodDef 与 PyMemberDef 深度解析
CPython 的 C API 文档将 Doc/c-api/structures.rst 作为所有 C 扩展开发者的"对象模型总纲":它定义了每个 Python 对象内存布局的公共头部(PyObject / PyVarObject)、用 C 实现 Python 可调用对象的 PyMethodDef 与各调用约定,以及把 C 结构体成员暴露为 Python 属性的 PyMemberDef / PyGetSetDef。本文完整继承该文档的核心内容,并结合 CPython 仓库头文件(Include/object.h、Include/methodobject.h、Include/descrobject.h 等)逐条剖析其内存布局、宏展开与实现细节,帮助你在编写 C 扩展时正确使用这些结构、宏与函数。
1. 基础对象类型与宏:每个 Python 对象的公共内存头部
CPython 中所有对象在内存表示的开头都共享一小段公共字段。文档 Doc/c-api/structures.rst 开篇即指出:这些字段由 PyObject 与 PyVarObject 两个类型表示,而这两个类型又由若干宏展开定义,几乎所有其他 Python 对象的定义都会直接或间接用到它们。
1.1 PyObject:对象的引用计数与类型指针
PyObject 是所有对象类型的"基类"。在普通的 release 构建下,它只包含对象的引用计数和指向类型对象的指针。文档强调:没有任何类型真正被声明为 PyObject,但每个 Python 对象指针都可以转换为 PyObject*——这是一种"手工实现的继承"。这段注释同样出现在 Include/object.h 中:
/* Nothing is actually declared to be a PyObject, but every pointer to
* a Python object can be cast to a PyObject*. This is inheritance built
* by hand. Similarly every pointer to a variable-size Python object can,
* in addition, be cast to a PyVarObject*.
*/
在标准(非 free-threaded、64 位)构建中,struct _object 的真实布局是:
struct _object {
_Py_ANONYMOUS union {
#if SIZEOF_VOID_P > 4
int64_t ob_refcnt_full; /* 在 ARM Clang 上为高效初始化而设 */
struct {
# if PY_BIG_ENDIAN
uint16_t ob_flags;
uint16_t ob_overflow;
uint32_t ob_refcnt;
# else
uint32_t ob_refcnt;
uint16_t ob_overflow;
uint16_t ob_flags;
# endif
};
#else
Py_ssize_t ob_refcnt; // part of stable ABI; do not change
#endif
_Py_ALIGNED_DEF(_PyObject_MIN_ALIGNMENT, char) _aligner;
};
PyTypeObject *ob_type; // part of stable ABI; do not change
};
(见 Include/object.h 中 struct _object 定义。)
各字段说明:
ob_refcnt(引用计数):即Py_REFCNT宏返回的值。文档明确要求不要直接使用该字段,而应使用Py_REFCNT、Py_INCREF与Py_DecRef(文档写作Py_DecRef)等宏和函数。从源码结构看,在 64 位平台该字段实际是一个 64 位 union 的低 32 位,高 16 位是ob_overflow(引用计数溢出区)、再高 16 位是ob_flags(如 static-immortal 标记),这使得引用计数可以用"饱和算术"避免溢出——细节可参考 Include/refcount.h 中关于 immortalization 策略的大段注释。ob_type(对象类型):不要直接访问,应使用Py_TYPE与Py_SET_TYPE。ob_mutex(每对象锁):仅存在于 free-threaded 构建(定义了Py_GIL_DISABLED),3.13 引入。源码中的 free-threaded 布局为:
struct _object {
_Py_ALIGNED_DEF(_PyObject_MIN_ALIGNMENT, uintptr_t) ob_tid;
uint16_t ob_flags;
PyMutex ob_mutex; // per-object lock
uint8_t ob_gc_bits; // gc-related state
uint32_t ob_ref_local; // local reference count
Py_ssize_t ob_ref_shared; // shared (atomic) reference count
PyTypeObject *ob_type;
};
文档特别警告:ob_mutex 预留给临界区 API(Py_BEGIN_CRITICAL_SECTION / Py_END_CRITICAL_SECTION)使用,绝不能用 PyMutex_Lock 直接加锁(可能死锁);若扩展需要自己的锁,应在对象结构体中新增独立的 PyMutex 字段。
Stable ABI 的差异:在 free-threaded Stable ABI(abi3t)中 PyObject 是不透明的(opaque),其大小与布局可能随 Python 版本变化;在非 free-threaded 的 abi3 中 ob_refcnt 和 ob_type 字段可用,但直接访问不推荐。
1.2 PyVarObject:带"长度"的对象头部
PyVarObject 是 PyObject 的扩展,增加 ob_size 字段,面向一切有长度概念的对象。Include/object.h 中的定义:
struct PyVarObject {
PyObject ob_base;
Py_ssize_t ob_size; // Number of items in variable part. Part of stable ABI
};
ob_base:公共对象头。通常不直接访问,而是把PyVarObject直接转换为PyObject。ob_size:一个"元素个数"字段,其内容应视为对象的内部实现细节。不要直接使用,应使用Py_SIZE宏。像PyObject_NewVar这样的对象创建函数通常会把它设置为请求的大小(元素数);创建之后可以用Py_SET_SIZE存入任意值。若要获取对象对外暴露的、len()会返回的长度,请使用PyObject_Length,而不是ob_size。
PyObject_VAR_HEAD 宏的头部注释(见 Include/object.h)也解释了变长容器的内存约定:结构体末尾声明一个含 1 个元素的数组,但实际 malloc 的空间足以容纳 ob_size 个元素;ob_size 是元素数而非字节数。
1.3 PyObject_HEAD 与 PyObject_VAR_HEAD 声明宏
-
PyObject_HEAD:用于声明长度不变的扩展类型,展开为:PyObject ob_base; -
PyObject_VAR_HEAD:用于长度逐实例变化的类型,展开为:PyVarObject ob_base;
1.4 初始化宏与 PyBaseObject_Type
-
PyObject_HEAD_INIT(type):展开为新的PyObject类型的初始化值:_PyObject_EXTRA_INIT 1, type, -
PyVarObject_HEAD_INIT(type, size):额外包含ob_size字段,展开为:_PyObject_EXTRA_INIT 1, type, size,其中
1是初始引用计数,_PyObject_EXTRA_INIT用于在支持 static-immortal 对象(64 位、非 free-threaded 构建)时填充高位标志位——这在 Include/internal/pycore_object.h 的内部实现中可以看到对应展开。 -
PyTypeObject PyBaseObject_Type:所有其他对象的基类,等价于 Python 中的object。
1.5 身份判断与类型/大小访问 API
文档列出了一组常用的单例判断函数(均为 3.10 新增)与类型/大小访问宏:
| API | 等价语义 | 说明 |
|---|---|---|
Py_Is(x, y) |
x is y |
判断两个对象是否同一对象;实现即指针比较 (x) == (y) |
Py_IsNone(x) |
x is None |
是否为 None 单例 |
Py_IsTrue(x) |
x is True |
是否为 True 单例 |
Py_IsFalse(x) |
x is False |
是否为 False 单例 |
Py_TYPE(o) |
— | 返回对象类型;返回的是借用引用(borrowed reference),不得用 Py_DECREF 释放。3.11 起改为 static inline 函数,参数类型不再是 const PyObject* |
Py_IS_TYPE(o, type) |
Py_TYPE(o) == type |
3.9 新增 |
Py_SET_TYPE(o, type) |
— | 3.9 新增。无检查、无引用计数地设置类型,属于非常底层操作,可能引发未定义行为;文档建议改用 PyObject_SetAttrString 设置 __class__ 属性 |
Py_SIZE(o) |
— | 读取 ob_size 字段;3.11 起改为 inline static 函数 |
Py_SET_SIZE(o, size) |
— | 3.9 新增,设置 ob_size |
关于 Py_SET_TYPE 还有一个容易忽视的引用计数规则(文档原文):如果 type 是堆类型(heap type),调用者必须为它新建一个引用;如果 o 的旧类型是堆类型,调用者必须释放对该类型的引用。
Py_TYPE 的实现本质在 Include/object.h 中一目了然:
static inline PyTypeObject* _Py_TYPE_impl(PyObject *ob)
{
return ob->ob_type;
}
而 free-threaded 构建下 Py_REFCNT 的语义完全不同(见 Include/refcount.h):它由线程本地的 ob_ref_local 与共享的原子计数 ob_ref_shared 组合计算得出,Py_REFCNT 返回的是一个"合并视图",这正是不推荐直接访问 ob_refcnt 字段的深层原因。
2. 实现函数与方法:PyMethodDef 与调用约定
2.1 五种 C 函数类型
文档定义了把 Python 可调用对象用 C 实现时的函数类型(其原型可在 Include/methodobject.h 中找到一一对应):
// 最典型的调用约定,参数是两个 PyObject*
PyObject *PyCFunction(PyObject *self, PyObject *args);
// METH_VARARGS | METH_KEYWORDS
PyObject *PyCFunctionWithKeywords(PyObject *self,
PyObject *args,
PyObject *kwargs);
// METH_FASTCALL
PyObject *PyCFunctionFast(PyObject *self,
PyObject *const *args,
Py_ssize_t nargs);
// METH_FASTCALL | METH_KEYWORDS
PyObject *PyCFunctionFastWithKeywords(PyObject *self,
PyObject *const *args,
Py_ssize_t nargs,
PyObject *kwnames);
// METH_METHOD | METH_FASTCALL | METH_KEYWORDS(3.9 新增)
PyObject *PyCMethod(PyObject *self,
PyTypeObject *defining_class,
PyObject *const *args,
Py_ssize_t nargs,
PyObject *kwnames);
通用契约:这些函数返回一个新引用(new reference)作为 Python 层的返回值;若返回 NULL,则应当已经设置了异常。
2.2 PyMethodDef:方法描述结构
PyMethodDef 用于描述扩展类型的一个方法,共 4 个字段(定义见 Include/methodobject.h):
struct PyMethodDef {
const char *ml_name; /* 方法名;NULL 表示 PyMethodDef 数组结束 */
PyCFunction ml_meth; /* C 实现指针 */
int ml_flags; /* METH_xxx 标志的组合 */
const char *ml_doc; /* docstring 内容,或 NULL */
};
要点:
ml_meth是 C 函数指针,函数类型可以不同但总是返回PyObject*;如果不是PyCFunction类型,编译器会在方法表中要求显式转换(Include/methodobject.h提供了_PyCFunction_CAST等宏来消除警告)。- 虽然
PyCFunction的第一个参数声明为PyObject*,但方法实现中通常使用 self 对象的具体 C 类型。
2.3 ml_flags:调用约定标志
ml_flags 是位域,标志分两类:调用约定(calling convention) 与绑定约定(binding convention)。源码中的位值定义(Include/methodobject.h):
#define METH_VARARGS 0x0001
#define METH_KEYWORDS 0x0002
/* METH_NOARGS 和 METH_O 不得与上面的标志组合使用 */
#define METH_NOARGS 0x0004
#define METH_O 0x0008
#define METH_CLASS 0x0010
#define METH_STATIC 0x0020
#define METH_COEXIST 0x0040
#define METH_FASTCALL 0x0080
调用约定一览:
METH_VARARGS(0x0001):典型约定,函数类型为PyCFunction。第一个参数是方法的 self 对象(模块函数则是模块对象),第二个参数(惯称 args)是一个元组,代表全部位置参数,通常用PyArg_ParseTuple或PyArg_UnpackTuple处理。METH_VARARGS | METH_KEYWORDS:函数必须为PyCFunctionWithKeywords类型,接收 self、args、kwargs 三个参数;kwargs 是全部关键字参数字典,若无关键字参数可能为NULL,通常用PyArg_ParseTupleAndKeywords处理。METH_FASTCALL(0x0080,3.7 新增,3.10 起进入稳定 ABI):快速调用约定,仅支持位置参数,函数类型为PyCFunctionFast。第二个参数是PyObject*的 C 数组(而非元组,避免构造元组的开销),第三个参数是数组长度。METH_FASTCALL | METH_KEYWORDS(3.7 新增):函数类型为PyCFunctionFastWithKeywords。关键字参数按 vectorcall 协议传递:额外第四参数是一个元组,表示关键字参数名(保证是字符串,无关键字时可能为NULL);关键字参数的值存放在 args 数组中、紧跟位置参数之后。METH_METHOD | METH_FASTCALL | METH_KEYWORDS(3.9 新增):在上面基础上支持 defining class——包含该方法的类,它可能是Py_TYPE(self)的超类。函数类型为PyCMethod,与METH_FASTCALL | METH_KEYWORDS相同,只是在 self 之后多了defining_class参数。METH_NOARGS(0x0004):无参数方法,函数必须仍有 2 个参数,第二个恒为NULL;未使用的参数可用Py_UNUSED抑制编译器警告。METH_O(0x0008):单对象参数方法,避免用"O"格式调用PyArg_ParseTuple;函数类型为PyCFunction,第二个PyObject*参数就是唯一的实参。
绑定约定(仅用于类方法,不能用于模块函数;一个方法至多设置其一):
METH_CLASS(0x0010):第一参数传类型对象而非实例,用于创建类似@classmethod装饰器的类方法。METH_STATIC(0x0020):第一参数传NULL,用于创建类似@staticmethod装饰器的静态方法。
另外还有一个控制方法加载行为的常量:
METH_COEXIST(0x0040):该方法的 PyCFunction 会替换已存在的同名定义。默认行为是跳过重复定义;由于 slot 包装器(slot wrapper)先于方法表加载,例如sq_containsslot 会先生成名为__contains__的包装方法并阻止同名 PyCFunction 加载。设置METH_COEXIST后,PyCFunction 将替换包装器对象与 slot 共存——这有助于性能,因为 PyCFunction 的调用比包装器对象调用优化程度更高。
2.4 PyCMethod 与 PyCFunction 对象及其访问 API
PyTypeObject PyCMethod_Type:Python C 方法对象对应的类型对象,Python 层即types.BuiltinMethodType。PyCMethod_Check(op)/PyCMethod_CheckExact(op):判断是否为PyCMethod_Type实例(或精确类型);前者考虑子类型,两者总是成功。PyCMethod_New(ml, self, module, cls)(3.9 新增):把ml(PyMethodDef*)变成一个 Python 可调用对象。调用者必须保证 ml 的生命周期长于该可调用对象(通常 ml 是 static 变量)。self 会在调用时作为 C 函数的 self 参数传入,可为NULL;module 是 Python 字符串,用于设置可调用对象的__module__属性,缺省可设为None或NULL;cls 作为 defining_class 传入,若ml->ml_flags设置了METH_METHOD则必须提供。PyTypeObject PyCFunction_Type:对应types.BuiltinFunctionType。PyCFunction_Check/PyCFunction_CheckExact:与PyCMethod_Check同理。PyCFunction_NewEx(ml, self, module):等价于PyCMethod_New(ml, self, module, NULL)。PyCFunction_New(ml, self):等价于PyCMethod_New(ml, self, NULL, NULL)。
从 Objects/methodobject.c 的实现可以印证这条调用链:PyCFunction_New → PyCFunction_NewEx → PyCMethod_New,即新旧 API 最终汇聚到同一个创建入口。
还有一组属性读取函数(均有带 GET_ 前缀的无检查版本):
| 函数 | 无检查版本 | 说明 |
|---|---|---|
PyCFunction_GetFlags(func) |
PyCFunction_GET_FLAGS |
返回创建时传入 ml_flags 的标志值;成功返回标志,失败返回 -1 并设置异常;func 不得为 NULL |
PyCFunction_GetFunction(func) |
PyCFunction_GET_FUNCTION |
返回 ml_meth 中的函数指针;失败返回 NULL 并设置异常 |
PyCFunction_GetSelf(func) |
PyCFunction_GET_SELF |
返回"self"对象(PyModuleDef 创建的模块函数即为模块对象);成功时返回借用引用 |
3. 访问扩展类型的属性:PyMemberDef 与 PyGetSetDef
3.1 PyMemberDef:把 C 结构体成员映射为 Python 属性
PyMemberDef 描述一个类型中"对应 C 结构体成员"的属性。定义类时,把这样的结构数组(以 NULL 结尾)放进 PyTypeObject.tp_members 槽位。字段依次为:
const char* name:成员名。NULL标记数组结束。字符串必须是静态的,不会拷贝。int type:成员在 C 结构体中的类型,取值见 3.3 节。Py_ssize_t offset:成员在类型对象结构体中的字节偏移。int flags:若干PyMemberDef.flags标志按位或组合,见 3.2 节。const char* doc:docstring 或NULL,字符串应静态,通常用PyDoc_STR定义。
默认(flags 为 0)成员可读写;用 Py_READONLY 标志设为只读。某些类型(如 Py_T_STRING)隐含 Py_READONLY。只有 Py_T_OBJECT_EX(以及旧式 T_OBJECT)成员可以被删除。
版本演进:PyMemberDef 自 3.12 起始终可用,此前需要 #include "structmember.h";PyMember_GetOne / PyMember_SetOne 同样自 3.12 起始终可用。3.14 起 Py_RELATIVE_OFFSET 也允许用于 "__vectorcalloffset__"、"__dictoffset__"、"__weaklistoffset__"。
堆类型的特殊偏移成员:对使用 PyType_FromSpec 等方式创建的堆类型,PyMemberDef 可以定义特殊成员 "__vectorcalloffset__"(对应 tp_vectorcalloffset),必须用 Py_T_PYSSIZET 且带 Py_READONLY 或 Py_READONLY | Py_RELATIVE_OFFSET:
static PyMemberDef spam_type_members[] = {
{"__vectorcalloffset__", Py_T_PYSSIZET,
offsetof(Spam_object, vectorcall), Py_READONLY},
{NULL} /* Sentinel */
};
(使用 offsetof 可能需要 #include <stddef.h>。)旧式的 tp_dictoffset 与 tp_weaklistoffset 也可用 "__dictoffset__" / "__weaklistoffset__" 定义,但扩展强烈建议改用 Py_TPFLAGS_MANAGED_DICT 与 Py_TPFLAGS_MANAGED_WEAKREF。
配套的单成员访问函数:
PyObject* PyMember_GetOne(const char *obj_addr, struct PyMemberDef *m):读取位于 obj_addr 的对象上、由 m 描述的属性;出错返回NULL。int PyMember_SetOne(char *obj_addr, struct PyMemberDef *m, PyObject *o):把该属性设置为 o;成功返回0,失败返回负值。
3.2 成员标志(Member flags)
标志值定义在 Include/descrobject.h 中:
#define Py_READONLY (1 << 0)
#define Py_AUDIT_READ (1 << 1) // Added in 3.10, harmless no-op before that
#define Py_RELATIVE_OFFSET (1 << 3)
Py_READONLY:不可写。Py_AUDIT_READ:读取前发出object.__getattr__审计事件(audit event)。Py_RELATIVE_OFFSET:该条目的offset是相对子类型专属数据(而非PyObject)的偏移。只能作为Py_tp_members槽位的一部分,在PyType_Spec.basicsize为负数时用PyType_FromSpec创建类时使用,且此时是强制的;Python 在类创建时从槽位设置tp_members会清除该标志,并把offset改写为相对PyObject结构体的偏移。
已废弃的历史宏:3.10 起,structmember.h 中的 RESTRICTED、READ_RESTRICTED、WRITE_RESTRICTED 被弃用——READ_RESTRICTED 与 RESTRICTED 等价于 Py_AUDIT_READ,WRITE_RESTRICTED 无效。3.12 起 READONLY 更名为 Py_READONLY,PY_AUDIT_READ 更名为带 Py_ 前缀的新名,新名称始终可用;旧头文件 Include/structmember.h 仍保留旧名并作为别名转发:
/* Types */
#define T_SHORT Py_T_SHORT
...
/* Flags */
#define READONLY Py_READONLY
#define PY_AUDIT_READ Py_AUDIT_READ
3.3 成员类型(Member types)
PyMemberDef.type 取下列宏之一,对应不同 C 类型;从 Python 访问时转换为等价 Python 类型,从 Python 设置时转换回 C 类型,无法转换则抛出 TypeError 或 ValueError。除非标注 (D),用此方式定义的属性不能用 del / delattr 删除:
| 宏 | C 类型 | Python 类型 |
|---|---|---|
Py_T_BYTE |
char |
int |
Py_T_SHORT |
short |
int |
Py_T_INT |
int |
int |
Py_T_LONG |
long |
int |
Py_T_LONGLONG |
long long |
int |
Py_T_UBYTE |
unsigned char |
int |
Py_T_UINT |
unsigned int |
int |
Py_T_USHORT |
unsigned short |
int |
Py_T_ULONG |
unsigned long |
int |
Py_T_ULONGLONG |
unsigned long long |
int |
Py_T_PYSSIZET |
Py_ssize_t |
int |
Py_T_FLOAT |
float |
float |
Py_T_DOUBLE |
double |
float |
Py_T_BOOL |
char(0 或 1) |
bool |
Py_T_STRING (*) |
const char * |
str (RO) |
Py_T_STRING_INPLACE (*) |
const char[] |
str (RO) |
Py_T_CHAR (**) |
char(0-127) |
str |
Py_T_OBJECT_EX (D) |
PyObject * |
object |
注释:(*) 为以零结尾、UTF-8 编码的 C 字符串;Py_T_STRING 的 C 表示是指针,Py_T_STRING_INPLACE 则把字符串直接存在结构体中。(**) 长度为 1 的字符串,仅接受 ASCII。(RO) 隐含 Py_READONLY。(D) 可删除,删除后指针置为 NULL,读取 NULL 指针抛出 AttributeError。
这些宏的数值编号定义在 Include/descrobject.h:
#define Py_T_SHORT 0
#define Py_T_INT 1
#define Py_T_LONG 2
#define Py_T_FLOAT 3
#define Py_T_DOUBLE 4
#define Py_T_STRING 5
#define Py_T_CHAR 7 /* 1-character string */
#define Py_T_BYTE 8 /* 8-bit signed int */
#define Py_T_UBYTE 9
#define Py_T_USHORT 10
#define Py_T_UINT 11
#define Py_T_ULONG 12
#define Py_T_STRING_INPLACE 13
#define Py_T_BOOL 14
#define Py_T_OBJECT_EX 16
#define Py_T_LONGLONG 17
#define Py_T_ULONGLONG 18
#define Py_T_PYSSIZET 19 /* Py_ssize_t */
在 3.12 之前的版本中,这些宏只有 #include "structmember.h" 时才可用,且不带 Py_ 前缀(如 T_INT)。该头文件仍提供旧名及两个已弃用类型:
T_OBJECT:类似Py_T_OBJECT_EX,但NULL会转换为None——这会导致 Python 层令人困惑的行为:删除该属性实际上会把它设为None。T_NONE:恒为None,必须搭配Py_READONLY使用。
3.4 PyGetSetDef:定义 getter 与 setter
PyGetSetDef 用于为类型定义"属性式"访问(参见 PyTypeObject.tp_getset 槽位描述),字段为:
const char* name:属性名;getter get:获取属性的 C 函数;setter set:可选的赋值/删除函数;为NULL时属性只读;const char* doc:可选 docstring;void* closure:可选用户数据指针,为 getter/setter 提供额外上下文。
函数签名与契约:
// getter:接收实例与 closure,成功返回新引用,失败返回 NULL 并设置异常
PyObject *(*getter)(PyObject *, void *);
// setter:接收实例、待设置的值与 closure;
// 属性被删除时第二个参数为 NULL;
// 成功返回 0,失败返回 -1 并设置异常
int (*setter)(PyObject *, PyObject *, void *);
4. 小结与延伸阅读
本文覆盖的 Doc/c-api/structures.rst 是 CPython C API 文档中承上启下的一篇:PyObject/PyVarObject 与 PyObject_HEAD 系列宏是一切扩展类型内存布局的地基;PyMethodDef 配合 METH_* 标志决定 C 函数如何被 Python 调用;PyMemberDef/PyGetSetDef 则完成 C 字段到 Python 属性的映射。编写 C 扩展时,建议按以下顺序核对仓库源码:
- Include/object.h:
struct _object/PyVarObject/ 各宏的当前实现; - Include/refcount.h:
Py_REFCNT在 free-threaded 与稳定 ABI 下的差异实现; - Include/methodobject.h 与 Objects/methodobject.c:调用约定标志位值与
PyCMethod_New创建链; - Include/descrobject.h 与 Include/structmember.h:成员类型编号、标志位及旧别名兼容层。
引用计数相关的宏与语义详见文档 Doc/c-api/refcounting.html 对应的 Doc/c-api/refcounting 源文件;对象内存布局的示意图可参考仓库中的 Objects/object_layout_313.png(3.13 布局,供理解 PyObject 头部与 GC 头部的相对位置)。
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