作者|strint

1背景

深度学习框架编译优化时,需要先根据计算逻辑形成一个逻辑计算图,然后再改写计算图,最后执行改写后的计算图。其中生成逻辑计算图方式有两种。


【资料图】

一种计算图生成是基于 trace tensor 的,跟踪 tensor 的执行路径。tensor 执行时,基于函数重载,可以落到支持 tensor 计算的框架自定义函数,该函数一般是 c++ 层的。c++ 层的自定义函数中,功能是用于生成一个 Operation 的符号表达。比如一个对于加法运算,trace 就是记录一个符号化的加法算子。如此一连串的运算就被转换了符号化的计算图。

另外一种计算图生成是基于 AST(抽象语法树) 解析的。在代码执行前,直接根据 Python 文本代码得到 Python AST,然后根据 AST 来翻译成计算图(也叫做中间代码 IR)。

Python(特指 CPython)解释器执行,第一阶段会先把 Python 源码解析成 AST,第二阶段根据 AST 生成和优化 ByteCode(字节码),第三阶段在虚拟机中执行 ByteCode。

基于 AST 解析的计算图生成,发生在这里的第一阶段;基于 trace tensor 的计算图生成,发生在第三阶段之后。

TorchDynamo 特别的地方在于其工作在第二阶段,动态修改 Python ByteCode,这样第三阶段执行的已经是修改后的 ByteCode了。

2

TorchDynamo 概述

TorchDynamo 是 PyTorch 新实验的 JIT 编译接口,支持使用 Python 在运行时修改动态执行逻辑,修改的时机是 CPython 的 ByteCode 执行前。这个思想类似 DynamoRIO(https://dynamorio.org) 项目,DynamoRIO 可以动态的修改 x86 机器码。

CPython 的每次函数调用会生成一个 Frame(或者叫 Stack),Frame 中带有的代码部分就是 ByteCode。CPython 运行时支持基于现有的 Frame 去设置一个自定义的 Frame,然后后面执行的就是自定义的 Frame。

TorchDynamo 的工作原理就是在运行时设置一个自定义的 Frame,该 Frame 中的 ByteCode 支持 CallBack 到 Python 层去修改。其提供的典型的修改接口是 FX Graph,也就是说 TorchDynamo 会分析 ByteCode,生成对应的 FX Graph,然后提供 FX Graph 的接口供用户自定义计算图。这种做法有如下优点:

可以支持所有的 Python 语法,因为如果在自定义 Frame 过程中的任何一点发现不支持,都可以选择不修改 Frame 而回退到原 Frame;

开销少,劫持发生在 Python 执行比较早的阶段(ByteCode 生成和优化阶段),而非 Python ByteCode 执行后的阶段,有时可以减少 Python ByteCode 的执行开销(猜测如果很多次 ByteCode 层面的函数调用被融合层成一次函数调用,的确可以缩减开销);

可以做到不增加编译带来的延迟(之前的基于 tensor trace 或者 ast 解析的做法,一般都有先编译执行所以编译开销无法掩盖,但是改写 ByteCode 这个做法,猜测是可以在识别出热点代码后,单独开一个线程去做编译,而不影响主线程工作。Python ByteCode 改写的 API 中有这种延迟编译的样例,peps.python.org/pep-052 )。

之前计算图生成机制(基于 trace tensor、基于 AST 解析的)中的几个问题,得到了缓解:

存在无法静态化的操作,之前一般需要显式的移除静态化作用域,现在总是允许不做编译,直接执行原 Python 代码,这样使得静态化标注变得简单;

打开静态图编译优化,之前编译时一般无法掩盖,现在有办法部分掩盖;

动态 shape 问题,因为有了编译时和运行时的掩盖,也可以得到缓解。

这种尽量优化、动态优化的设计,最大程度了照顾了代码开发的体验,让编译优化上手变得更简单了。这是 TorchDynamo 带来的最主要的好处。这种做法非常符合 PyTorch 的 Python First、Eager First、User Experience First的偏好。但是这个设计对于寻求最好的性能、最方便的静态化部署这两个目标并没有改善。

3

CPython 的标准执行流程

上文提到了 CPython 的执行从 Python 文本代码,到 AST,到 ByteCode。这里用一个示例展开看一下。Python 的标准组件非常易用,可以在 Python 层用 ast 组件来查看 AST,可以用 compile 内置函数来编译 ByteCode,可以用 exec 系统函数来执行 ByteCode。我们先在代码开头导入相关组件:

import astimport disimport sys

然后我们构造一个 python 代码,可以看到 src_code 就是普通的字符串。其中包含了一段普通的 python 内置的乘法,一段深度学习的 tensor scalar 加法,最后一段是当前Python Frame 中的 ByteCode 关联对象的打印(用于一个检验,后面会提到)。

print("=== source code ===")src_code = """# normal python operationx = 1x = x * 2# tensor operationy = dl_framework.ones((1, 2))z = x + yprint(z)# print python framef = sys._getframe()# print the code objectprint(f.f_code)"""print(src_code)

然后使用 ast 组件来生成这段代码的 AST。

print("=== source code to ast ===")# 把源代码解析成 ASTast_obj = ast.parse(src_code)# 打印 ASTprint(ast.dump(ast_obj))

可以得到 AST,这里展示的结果额外做了格式化,另外删减掉了和计算逻辑无关的打印 frame 的部分,代码和其 AST 的对应关系参见注释。AST解析是纯文本层面的,`dl_framework` 还没有被 import 进来,AST解析仍然可以正常工作。AST 基本是一个多叉树的结构,每个节点对应一个表达式,节点子节点代表子表达式。以 `x = x + 2` 为例,Assign 是一个节点,是赋值运算,被赋值的是 `x`,赋值的值是一个二元乘法运算。

Module(body=[ # x = 1 Assign(targets=[Name(id="x", ctx=Store())], value=Constant(value=1, kind=None), type_comment=None), # x = x * 2 Assign(targets=[Name(id="x", ctx=Store())], value=BinOp(left=Name(id="x", ctx=Load()), op=Mult(), right=Constant(value=2, kind=None)), type_comment=None), # y = dl_framework.ones((1, 2)) Assign(targets=[Name(id="y", ctx=Store())], # dl_framework.ones((1, 2)) value=Call(func=Attribute(value=Name(id="dl_framework", ctx=Load()), attr="ones", ctx=Load()), args=[Tuple(elts=[Constant(value=1, kind=None), Constant(value=2, kind=None)], ctx=Load())], keywords=[]), type_comment=None), # z = x + y Assign(targets=[Name(id="z", ctx=Store())], # x + y value=BinOp(left=Name(id="x", ctx=Load()), op=Add(), right=Name(id="y", ctx=Load())), type_comment=None), # print(z) Expr(value=Call(func=Name(id="print", ctx=Load()), args=[Name(id="z", ctx=Load())], keywords=[])), # 省略了打印 frame 的代码],type_ignores=[])

Python AST 生成后,可以利用系统函数 `compile` 把它转成 ByteCode 字节码。解释器执行也存在编译的环节,只不过是编译成字节码。

print("=== ast to bytecode ===")# 编译成 ByteCodecode_obj = compile(ast_obj, filename="", mode="exec")print(code_obj)# 展示 ByteCode 的语法糖byte_obj = dis.Bytecode(code_obj)print(byte_obj.dis())

`print(code_obj)`的结果是 ` at 0x7ff79bb5c660, file "", line 3>`,这里可以看到生成的 code object 对象的指针是 `0x7ff79bb5c660`,后面我们在执行字节码时,会再次看到这个指针。

`print(byte_obj.dis())` 的结果如下,每一行对应一条字节码,也即一条指令, 通过字面含义基本可以看出是在做什么:

# x = 1 3 0 LOAD_CONST 0 (1) 2 STORE_NAME 0 (x) # x = x * 2 4 4 LOAD_NAME 0 (x) 6 LOAD_CONST 1 (2) 8 BINARY_MULTIPLY 10 STORE_NAME 0 (x) # y = dl_framework.ones((1, 2)) 7 12 LOAD_NAME 1 (dl_framework) 14 LOAD_METHOD 2 (ones) 16 LOAD_CONST 2 ((1, 2)) 18 CALL_METHOD 1 20 STORE_NAME 3 (y) # x = x + y 8 22 LOAD_NAME 0 (x) 24 LOAD_NAME 3 (y) 26 BINARY_ADD 28 STORE_NAME 4 (z) # print(z) 9 30 LOAD_NAME 5 (print) 32 LOAD_NAME 4 (z) 34 CALL_FUNCTION 1 36 POP_TOP # 省略了打印 frame 的代码

得到 ByteCode 之后,就可以传递给 Python VM 执行了。在真正执行前,先做了一下 ByteCode 中指令的打印,实际 Python VM 执行时,也基本是这样遍历每一行指令,然后执行指令。可以想象,如果这些指令被修改,就可以让 Python VM 执行自定义的指令了。

print("=== execute bytecode ===")# print instructionfor instr in byte_obj: print(instr.opname, instr.opcode)# You can also do `import torch as dl_framework``import oneflow as dl_framework# execute bytecodeexec(code_obj)

字节码的执行结果如下。只需要在真正执行前,把 `dl_framework`导入就好,然后可以看到 tensor 计算的结果,是符合预期的。

frame(或者叫 stack)是运行时的对象,对应一个函数调用的栈,在执行时被创建。frame 中要执行的指令就是之前创建的 ByteCode。

在运行时之前,像我们之前看到的,存在一个编译时进行 AST 和 ByteCode 的编译,之前编译时生成的 code object 对象的指针是 `0x7ff79bb5c660`。

在运行时,可以获取当前的 frame,然后通过 `frame.f_code`拿到当前 frame 里面包含的 ByteCode(即 code object),可以发现它的指针就是之前编译时生成的那个。

# print(z) 的结果tensor([[3., 3.]], dtype=oneflow.float32)# 运行时获取当前 frame ,然后打印 frame 中的 ByteCode 对象的结果# f = sys._getframe()# print(f.f_code) at 0x7f5cea7f1660, file "", line 3>

到此,窥见了一下 Python 源码到 AST, AST 到 ByteCode,ByteCode 到 Frame 执行这个默认的 Python 执行流程。TorchDynamo 用下图做了简单的介绍:

其中 foo 对应一个 Python 函数,即上文介绍的 Python Source Code。PyCodeObject 是上文介绍的 code object (ByteCode)在 C 代码层面对应的类。PyFrameObject 是上文介绍的 Frame 在 C 代码层面对应的类,它包含了代码段 PyCodeObject。_PyEval_EvalFrameDefault 对应上文介绍的 exec,它执行一个 Frame,即运行 Frame 带有的 `PyCodeObject`。

现在我们看一下 CPython 在 C 层面的执行 Frame 的实现,对应 _PyEval_EvalFrameDefault(https://github.com/python/cpython/blob/d48ecebad5ac78a1783e09b0d32c211d9754edf4/Python/ceval.c#L757)。它的主逻辑就是取 ByteCode 指令和执行指令(https://github.com/python/cpython/blob/d48ecebad5ac78a1783e09b0d32c211d9754edf4/Python/ceval.c#L1080):

co = f->f_code; // 从 PyFrameObject* f 中取出 PyCodeObject* ,放到 co 中 names = co->co_names; consts = co->co_consts; fastlocals = f->f_localsplus; freevars = f->f_localsplus + co->co_nlocals; // 从 co 中取出第一条指令 first_instr = (_Py_CODEUNIT *) PyBytes_AS_STRING(co->co_code); next_instr = first_instr;#define NEXTOPARG() do { \ _Py_CODEUNIT word = *next_instr; \ opcode = _Py_OPCODE(word); \ oparg = _Py_OPARG(word); \ // 指向下一条指令 next_instr++; \ } while (0) // 循环执行指令 for (;;) { // 从当前的指令 next_instr 中获取 opcode NEXTOPARG(); switch (opcode) { // 执行 op code,参见下个部分 } }

每个指令类型对应一个 opcode,它是一个数值,执行 opcode(https://github.com/python/cpython/blob/d48ecebad5ac78a1783e09b0d32c211d9754edf4/Python/ceval.c#L1266),这里的 opcode 可以清晰的看到和之前我们打印的 ByteCode 的类型对应关系:

#define TARGET(opcode) \ case opcode: switch (opcode) { // TARGET 就是一个 case // load TARGET(LOAD_FAST) { PyObject *value = GETLOCAL(oparg); if (value == NULL) { format_exc_check_arg(PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, PyTuple_GetItem(co->co_varnames, oparg)); goto error; } Py_INCREF(value); PUSH(value); FAST_DISPATCH(); } // store TARGET(STORE_FAST) { PyObject *value = POP(); SETLOCAL(oparg, value); FAST_DISPATCH(); } // 二元加法 TARGET(BINARY_ADD) { PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { sum = unicode_concatenate(left, right, f, next_instr); /* unicode_concatenate consumed the ref to left */ } else { sum = PyNumber_Add(left, right); Py_DECREF(left); } Py_DECREF(right); SET_TOP(sum); if (sum == NULL) goto error; DISPATCH(); } // 函数调用 TARGET(CALL_FUNCTION) { PyObject **sp, *res; PCALL(PCALL_ALL); sp = stack_pointer; res = call_function(&sp, oparg, NULL); stack_pointer = sp; PUSH(res); if (res == NULL) { goto error; } DISPATCH(); }    }

以上总结了 Python的默认执行流程。

4

TorchDynamo 的工作流程

TorchDynamo 在标准的 Python 执行流程中做的主要改变就是支持修改 Frame 执行前的 ByteCode。我们暂时不关注 AST 生成,看 Python 的执行流程,是 Python Source Code -> ByteCode -> Evaluate. TorchDynamo 支持 Python Source Code -> ByteCode -> [ByteCode rewrite] -> Evaluate。

ByteCode rewrite 的工作方式是把一段 ByteCode 转成 FX Graph,然后调用用户自定义的 FX Graph 改写执行逻辑,生成一个可以经过编译的执行函数。然后把该段 ByteCode 替换成函数调用 ByteCode,而调用的函数就是经过编译的执行函数。从而实现编译优化的功能。

FX Graph 支持了在 Python 层做代码改写,提高了写编译 Pass 的便利性,这里不做深入,可以参考资料1(https://pytorch.org/docs/stable/fx.html)和2(https://zhuanlan.zhihu.com/p/416165157)。

ByteCode rewrite 发生在 ByteCode 执行前。同样的 Source Code,每次执行都会走到这个步骤,都可以选择是否进行 ByteCode rewrite,或者选择进行什么样的 rewrite,还可以支持 rewrite 结果的缓存和复用。这体现了 Dynamo 的动态性。

下面看一个 TorchDynamo 下 fn() 函数编译的的例子:

# 一个普通的函数def fn(a, b): x = a + b x = x / 2.0 if x.sum() < 0: return x * -1.0 return x # torchdynamo 函数接口with torchdynamo.optimize(custom_compiler): fn(torch.randn(10), torch.randn(10))

fn() 函数对应的原始的 python ByteCode,和代码对应的关系参见其中的注释:

# x = a + b 0 LOAD_FAST 0 (a) 2 LOAD_FAST 1 (b) 4 BINARY_ADD 6 STORE_FAST 2 (x) # x = x / 2.0 8 LOAD_FAST 2 (x) 10 LOAD_CONST 1 (2.0) 12 BINARY_TRUE_DIVIDE 14 STORE_FAST 2 (x) # if x.sum() < 0: 16 LOAD_FAST 2 (x) 18 LOAD_METHOD 0 (sum) 20 CALL_METHOD 0 22 LOAD_CONST 2 (0) 24 COMPARE_OP 0 (<) 26 POP_JUMP_IF_FALSE 36 # return x * -1.0 28 LOAD_FAST 2 (x) 30 LOAD_CONST 3 (-1.0) 32 BINARY_MULTIPLY 34 RETURN_VALUE # return x 36 LOAD_FAST 2 (x) 38 RETURN_VALUE

经过 TorchDynamo 动态改写后的 ByteCode:

# x = a + b # x = x / 2.0 # x.sum() < 0 # 上面两行被转换成了 __compiled_fn_0 # __compiled_fn_0 会返回 x 和 x.sum() < 0 组成的 tuple 0 LOAD_GLOBAL 1 (__compiled_fn_0) 2 LOAD_FAST 0 (a) 4 LOAD_FAST 1 (b) 6 CALL_FUNCTION 2 8 UNPACK_SEQUENCE 2 10 STORE_FAST 2 (x) 12 POP_JUMP_IF_FALSE 22 # x * -1.0 被转换成了 __compiled_fn_1 14 LOAD_GLOBAL 2 (__compiled_fn_1) 16 LOAD_FAST 2 (x) 18 CALL_FUNCTION 1 20 RETURN_VALUE # return x 22 LOAD_FAST 2 (x) 24 RETURN_VALUE

可以看到新增了两个函数调用, `__compiled_fn_0` 和 `__compiled_fn_1` ,这两个函数对应的代码逻辑参见 bytecode 中的注释。这两个函数对应的 fx graph 如下:

__compiled_fn_0:opcode name target args kwargs------------- ------- --------------------------- ---------------- --------placeholder a_0 a_0 () {}placeholder b_1 b_1 () {}call_function add (a_0, b_1) {}call_function truediv (add, 2.0) {}call_method sum_1 sum (truediv,) {}call_function lt (sum_1, 0) {}output output output ((truediv, lt),) {}__compiled_fn_1:opcode name target args kwargs------------- ------ ----------------------- ----------- --------placeholder x_4 x_4 () {}call_function mul (x_4, -1.0) {}output output output (mul,) {}

在 ByteCode rewrite 的最后,TorchDynamo 为这一段代码的输入创建两个 Guard:

局部参数 a 必须是一个 Tensor

局部参数 b 必须是一个 Tensor

该 fn 函数被再次调用时,如果符合这两个条件,则可以命中缓存的 TrochDynamo 处理结果;否则下次 fn 执行时,会触发新的 ByteCode 分析和变换。

另外,对于和 tensor 无关的、比较特别的 python 代码,其 ByteCode 会保持原状。这样就达到了不需要用户标注区域、自动寻找优化机会的设计目标。

现在看下 TorchDynamo 执行的流程总结:

可以看到它把原来的 PyFrameObject 替换成了 Patched PyFrameObject,这个是 CPython 支持的特性。这个 Patched PyFrameObject 中最主要的改动就是 Frame 中的 ByteCode (即 PyCodeObject)被修改了,原来的 PyCodeObject 变成了 Transformed PyCodeObject。而这个被改写的 PyCodeObject 如上文和上图所示,主要是部分 ByteCode 被替换成了调用被编译过函数。这个被编译过的函数,支持自定义编译逻辑,当前默认的编译接口是 FX Graph。

这部分基本参考了Dynamo的官方介绍(https://dev-discuss.pytorch.org/t/torchdynamo-an-experiment-in-dynamic-python-bytecode-transformation/361)。

5

TorchDynamo 修改 Python ByteCode 的实现

Python ByteCode 修改主要依赖 PEP 523(https://peps.python.org/pep-0523/) 提供的执行自定义 Frame Evaluation API。默认的 Eval Frame 逻辑入口函数是 _PyEval_EvalFrame,默认情况,它会直接调用 _PyEval_EvalFrameDefault() 来处理没被修改的 frame,但是如果发现存在一个自定义的 Eval Frame 函数,就会执行自动线的函数。

CPython _PyEval_EvalFrame 函数实现(https://github.com/python/cpython/blob/76449350b3467b85bcb565f9e2bf945bd150a66e/Include/internal/pycore_ceval.h#L84),所以只要在 ByteCode 执行前,设置一个自定义的 eval frame 函数即可:

static inline PyObject*_PyEval_EvalFrame(PyThreadState *tstate, struct _PyInterpreterFrame *frame, int throwflag){ EVAL_CALL_STAT_INC(EVAL_CALL_TOTAL); if (tstate->interp->eval_frame == NULL) { // 这是默认的 eval frame return _PyEval_EvalFrameDefault(tstate, frame, throwflag); } // 如果存在 eval_frame 就会被执行 return tstate->interp->eval_frame(tstate, frame, throwflag);}

可以看到 TorchDynamo 正是这么做的。第一步,在 Python 层基于 ContextManger 在进入 Dynamo 作用域时,就触发 eval_frame 的设置,实现(https://github.com/pytorch/pytorch/blob/4068c5467d496cd3c09a841f40adacedf3ab41a0/torch/_dynamo/eval_frame.py#L128):

# torch._dynamo.optimize(...) 对应的 context manager.class _TorchDynamoContext: def __init__( self, callback: DynamoCallback, ): super().__init__() assert callable(callback) or callback is False or callback is None self.callback: DynamoCallback = callback self.prior: Union[Unset, DynamoCallback] = unset def __enter__(self): # 设置 eval_frame,记录之前的 eval frame self.prior = set_eval_frame(self.callback) def __exit__(self, exc_type, exc_val, exc_tb): assert self.prior is not unset # 恢复之前的 eval frame set_eval_frame(self.prior)

这里先大致认为设置的 DynamoCallback 对应一个自定义的 eval frame 所需的参数,通常是自定义的 eval frame 中所需的编译逻辑。

看下 set_eval_frame ,C 代码层面的实现(https://github.com/pytorch/pytorch/blob/eaf4fe3d2b7096579b05b52d543756f74d0e91e7/torch/csrc/dynamo/eval_frame.c#L446),它有点绕但最终走到了这里(https://github.com/pytorch/pytorch/blob/eaf4fe3d2b7096579b05b52d543756f74d0e91e7/torch/csrc/dynamo/eval_frame.c#L121),也是设置 tstate->interp->eval_frame ,把 eval_frame 设置成自定义的 custom_eval_frame_shim:

// custom_eval_frame_shim 是自定义的 frameinline static void enable_eval_frame_shim(PyThreadState* tstate) { if (tstate->interp->eval_frame != &custom_eval_frame_shim) { // First call // 设置自定义的 eval frame tstate->interp->eval_frame = &custom_eval_frame_shim; }}

现在回头看一下 PEP 523 提供的 Python JIT 编译器的自定义 frame 执行的样例,它提供了一个比较标准的模版(注意笔者对例子做了微调,原文有多余和不合理的地方)。在自定义 eval frame 之前,一般还需要自定义一个存放自定义 ByteCode 的数据结构,可以认为是自定义编译结果,比如样例中自定义编译结果包括3个字段:

exec_count, 代表改 frame 被执行的次数;

jit_failed, 代表之前 jit 编译是否失败过;

jit_code,代表 jit 编译过后的自定义 ByteCode;

据此,来看下自定义 eval frame 的样例:

# 输入原始的 framedef eval_frame(frame, throw_flag): # 获取 frame 中的 code object 中的存放自定义编译结果的字段 pyjion_code = frame.code.co_extra if not pyjion_code: # 不如不存在,就设置一个空的默认值 frame.code.co_extra = PyjionJittedCode() elif not pyjion_code.jit_failed: # 如果之前 jit 执行成功 if pyjion_code.jit_code: # 如果存在 jit 生成的 bytecode,就执行它 return pyjion_code.eval(pyjion_code.jit_code, frame) elif pyjion_code.exec_count > 20000: # 没有 jit 编译过,且 frame 被执行超过 20000 次,就尝试进行 jit 编译 # 如果不存在 jit 生成的 bytecode,就 jit 编译生成它 if jit_compile(frame): # 如果 jit 编译成功,就执行 jit 编译的 bytecode return pyjion_code.eval(pyjion_code.jit_code, frame) else: # 如果 jit 编译失败,就记录下,后面不再编译 pyjion_code.jit_failed = True # 增加 frame 执行次数计数 pyjion_code.exec_count += 1 # 执行默认的 frame return _PyEval_EvalFrameDefault(frame, throw_flag)

下面接着看 TorchDynamo 自定义 evale frame 的实现。在了解具体的自定义 frame 执行逻辑前,有个前置知识是 PyFrameObject 中的 PyCodeObject 为了执行自定义 frame 增加了一个 co_extra 字段,用来让用户放置自定义的数据,一般是存放自定义编译结果(https://peps.python.org/pep-0523/#expanding-pycodeobject)。

typedef struct { ... void *co_extra; /* 自定义的 frame 需要的自定义数据 */} PyCodeObject;

TorchDynamo 在自定义编译结果的类型是 CacheEntry,其中最重要的字段是 code,是被编译器修改后的 ByteCode:

typedef struct cache_entry { // check the guards: lambda: : bool PyObject* check_fn; // modified user bytecode (protected by check_fn"s guards) PyCodeObject* code; // on a cache miss, linked list of next thing to try struct cache_entry* next;} CacheEntry;

现在看下自定义的 eval frame 逻辑 custom_eval_frame_shim(https://github.com/pytorch/pytorch/blob/eaf4fe3d2b7096579b05b52d543756f74d0e91e7/torch/csrc/dynamo/eval_frame.c#L342):

static PyObject* _custom_eval_frame(PyThreadState* tstate, PyFrameObject* frame, int throw_flag, PyObject* callback) { // 获取当前 frame 的 PyCodeObject 的 extra 字段用于后面设置 // 该字段用于放置自定义的编译结果 CacheEntry* extra = get_extra(frame->f_code); // callback 即上文说的自定义编译器 // 使用 callback 进行 bytecode 的修改,即编译 // 编译结果写在了 frame->f_code中的 extra 中 PyObject* result = call_callback(callback, (PyObject*)frame, cache_size(extra)); if (result != Py_None) { // 缓存编译结果 extra = create_cache_entry(extra, result); Py_DECREF(result); // 执行自定义的 frame // eval_custom_code 最终会调用 CPython 接口 _PyEval_EvalFrameDefault 来执行计算 // 其中 extra->code 中存放的就自定义编译器生成的 ByteCode // 所以最终 _PyEval_EvalFrameDefault 执行的是编译器生成的 ByteCode return eval_custom_code(tstate, frame, extra->code, throw_flag); }}inline static PyObject* eval_custom_code(PyThreadState* tstate, PyFrameObject* frame, PyCodeObject* custom_code, int throw_flag) { // 使用 custom_code 创建一个自定义的 frame PyFrameObject* shadow_frame = PyFrame_New(tstate, custom_code, frame->f_globals, NULL); // 调用 Python 的 frame 执行自定义 frame return _PyEval_EvalFrameDefault(tstate, shadow_frame, throw_flag);}

到这里,已经清楚了修改 Python ByteCode 执行的主线逻辑。

6

小结

这里对 Python 的执行和 TorchDynamo 的主要原理做了初探,主要是自定义 Eval Frame 的实现技巧。其它相关的 Python ByteCode 标准,ByteCode 到 FX Graph 的转换,ByteCode 的改写等内容还没涉及。

参考资料  

tenthousandmeters.com/b (https://tenthousandmeters.com/blog/python-behind-the-scenes-1-how-the-cpython-vm-works/)

peps.python.org/pep-052 (https://peps.python.org/pep-0523/)

dev-discuss.pytorch.org (https://dev-discuss.pytorch.org/t/torchdynamo-an-experiment-in-dynamic-python-bytecode-transformation/361)

(原文:https://zhuanlan.zhihu.com/p/589115427) 其他人都在看

李白:你的模型权重很不错,可惜被我没收了

单RTX 3090训练YOLOv5s,时间减少11小时

OpenAI掌门Sam Altman:AI下一个发展阶段

32篇年度最佳AI论文;Python编译器Codon开源

对比四大深度学习框架,我发现都关注两大问题

比快更快,开源Stable Diffusion刷新作图速度

OneEmbedding:单卡训练TB级推荐模型不是梦

欢迎Star、试用OneFlow最新版本:GitHub - Oneflow-Inc/oneflow: OneFlow is a deep learning framework designed to be user-friendly, scalable and efficient.OneFlow is a deep learning framework designed to be user-friendly, scalable and efficient. - GitHub - Oneflow-Inc/oneflow: OneFlow is a deep learning framework designed to be user-friendly, scalable and efficient.https://github.com/Oneflow-Inc/oneflow/

推荐内容

  • TorchDynamo初探:Python ByteCode的动态修改-天天观察
    TorchDynamo初探:Python ByteCode的动态修改-天天观察

  • 如何看待PyTorch 2.0?
    如何看待PyTorch 2.0?

  • ChatGPT进化的秘密-世界快报
    ChatGPT进化的秘密-世界快报

  • 对比PyTorch、TensorFlow、JAX、Theano,我发现都在关注两大问题-环球头条
    对比PyTorch、TensorFlow、JAX、Theano,我发现都在关注两大问题-环球头条

  • DevEco Studio 3.1差异化构建打包,提升多版本应用开发效率-天天热门
    DevEco Studio 3.1差异化构建打包,提升多版本应用开发效率-天天热门

  • YOLOv5全面解析教程①:网络结构逐行代码解读
    YOLOv5全面解析教程①:网络结构逐行代码解读

  • OpenAI掌门人Sam Altman:AI的下一个发展阶段
    OpenAI掌门人Sam Altman:AI的下一个发展阶段

  • 下载量突破10亿,MinIO的开源启示录-世界快播
    下载量突破10亿,MinIO的开源启示录-世界快播

  • 用一张图说一说 ChatGPT 内部技术工作流程
    用一张图说一说 ChatGPT 内部技术工作流程

  • 一块RTX 3090加速训练YOLOv5s,时间减少11个小时,速度提升20%-全球最新
    一块RTX 3090加速训练YOLOv5s,时间减少11个小时,速度提升20%-全球最新

  • YOLOv5全面解析教程①:网络结构逐行代码解析-环球头条
    YOLOv5全面解析教程①:网络结构逐行代码解析-环球头条

  • Stable Diffusion 2.0 来了
    Stable Diffusion 2.0 来了

  • OneFlow源码解析:自动微分机制-当前时讯
    OneFlow源码解析:自动微分机制-当前时讯

  • 开源风暴吞噬AI界?从Stable Diffusion的爆火说起-世界观速讯
    开源风暴吞噬AI界?从Stable Diffusion的爆火说起-世界观速讯

  • OneFlow-ONNX v0.6.0正式发布-世界速讯
    OneFlow-ONNX v0.6.0正式发布-世界速讯

  • 大模型狂潮背后:AI基础设施的“老化”与改造工程-全球观焦点
    大模型狂潮背后:AI基础设施的“老化”与改造工程-全球观焦点

  • 李白:你的模型权重很不错,可惜被我没收了
    李白:你的模型权重很不错,可惜被我没收了

  • Compose Material 3 稳定版现已发布 | 2022 Android 开发者峰会
    Compose Material 3 稳定版现已发布 | 2022 Android 开发者峰会

  • 腾讯魏巍:Eunomia云原生资源编排优化
    腾讯魏巍:Eunomia云原生资源编排优化

  • 打造高安全数字基础设施:中国电子云服务关键行业的宣言-天天热门
    打造高安全数字基础设施:中国电子云服务关键行业的宣言-天天热门

  • Moka发布“人才数字经济”四大趋势:数智化是关键
    Moka发布“人才数字经济”四大趋势:数智化是关键

  • OPPO广告联盟战略升级,全面提升开发者变现效率-天天热门
    OPPO广告联盟战略升级,全面提升开发者变现效率-天天热门

  • 边缘计算在视频直播场景的应用与实践
    边缘计算在视频直播场景的应用与实践

  • Milvus 2.1 版本更新 - 简单可信赖、性能持续提升-天天播报
    Milvus 2.1 版本更新 - 简单可信赖、性能持续提升-天天播报

  • 京东杨业飞:京东云原生大规模实践之路-全球热资讯
    京东杨业飞:京东云原生大规模实践之路-全球热资讯

  • 每日聚焦:营销服数智化的必经之路——多模态交互实践与展望
    每日聚焦:营销服数智化的必经之路——多模态交互实践与展望

  • 全球关注:三七互娱何琦:游戏平台上云是花钱还是省钱
    全球关注:三七互娱何琦:游戏平台上云是花钱还是省钱

  • 快播:字节跳动多媒体实验室联合 ISCAS 举办第二届神经网络视频编码竞赛
    快播:字节跳动多媒体实验室联合 ISCAS 举办第二届神经网络视频编码竞赛

  • 天天最新:贡献全球1/5核心突破,腾讯云第六年登上KVM贡献榜
    天天最新:贡献全球1/5核心突破,腾讯云第六年登上KVM贡献榜

  • 【天天速看料】直播案例剖析:手机降频对直播声音体验的影响
    【天天速看料】直播案例剖析:手机降频对直播声音体验的影响

  • 我国探月工程有了新进展 第四期已立项
    我国探月工程有了新进展 第四期已立项

  • 我国首个静止轨道Q/V频段星地通信试验系统成功运行 填补了我国相关领域系统的建设和研究空白
    我国首个静止轨道Q/V频段星地通信试验系统成功运行 填补了我国相关领域系统的建设和研究空白

  • 焦点热文:Apache Flink Table Store 0.2.0 发布
    焦点热文:Apache Flink Table Store 0.2.0 发布

  • 全球关注:一条推特触动开发者神经:我们不想做运维!
    全球关注:一条推特触动开发者神经:我们不想做运维!

  • 环球今头条!作业帮董晓聪:作业帮云原生降本增效实践之路
    环球今头条!作业帮董晓聪:作业帮云原生降本增效实践之路

  • 全球快资讯:加码云原生,斩获 19000 Star 的开源国产数据库又上新
    全球快资讯:加码云原生,斩获 19000 Star 的开源国产数据库又上新

  • 上海:到2025年L2和L3级智能驾驶新车生产占比超七成
    上海:到2025年L2和L3级智能驾驶新车生产占比超七成

  • 环球最新:逆向工程:揭示Google Colab未公开的秘密
    环球最新:逆向工程:揭示Google Colab未公开的秘密

  • 焦点快播:从Core Dump中提取CUDA的报错信息
    焦点快播:从Core Dump中提取CUDA的报错信息

  • 资讯:火山引擎徐鑫:工程师如何与云原生共同成长
    资讯:火山引擎徐鑫:工程师如何与云原生共同成长

  • 微速讯:阿里云机器学习PAI开源中文NLP算法框架EasyNLP,助力NLP大模型落地
    微速讯:阿里云机器学习PAI开源中文NLP算法框架EasyNLP,助力NLP大模型落地

  • 世界要闻:9篇分布式机器学习系统经典论文;深度学习硬件的黄金十年|AI系统前沿动态...
    世界要闻:9篇分布式机器学习系统经典论文;深度学习硬件的黄金十年|AI系统前沿动态...

  • 我国成功发射遥感三十三号02星 主要用于科学试验、国土资源普查、农产品估产及防灾减灾等领域
    我国成功发射遥感三十三号02星 主要用于科学试验、国土资源普查、农产品估产及防灾减灾等领域

  • 环球即时看!中海庭罗凯:Prometheus监控Argo Workflow云原生工作流的方法
    环球即时看!中海庭罗凯:Prometheus监控Argo Workflow云原生工作流的方法

  • 世界新动态:青云霍秉杰:一文读懂Prometheus长期存储主流方案
    世界新动态:青云霍秉杰:一文读懂Prometheus长期存储主流方案

  • 天天消息!基于AI算法的数据库异常监测系统的设计与实现
    天天消息!基于AI算法的数据库异常监测系统的设计与实现

  • 动态:OneFlow源码解析:Tensor类型体系与Local Tensor
    动态:OneFlow源码解析:Tensor类型体系与Local Tensor

  • 环球聚焦:写代码,必须要优雅...
    环球聚焦:写代码,必须要优雅...

  • 【全球报资讯】AIOps:实现运维智能化的一大利器
    【全球报资讯】AIOps:实现运维智能化的一大利器

  • “轩岚诺”加强成为今年首个超强台风 明起影响我国东部海域
    “轩岚诺”加强成为今年首个超强台风 明起影响我国东部海域

  • 【全球新视野】金融核心系统云原生转型的三个挑战、六个误区和四个步骤
    【全球新视野】金融核心系统云原生转型的三个挑战、六个误区和四个步骤

  • 国家燃料电池技术创新中心正式挂牌:全球最大氢燃料电池发动机研发基地
    国家燃料电池技术创新中心正式挂牌:全球最大氢燃料电池发动机研发基地

  • 今日视点:腾讯方睿:详解Kubernetes资源拓扑感知调度
    今日视点:腾讯方睿:详解Kubernetes资源拓扑感知调度

  • 天天热文:腾讯陈东东:Caelus全场景在离线混部的思考与实践
    天天热文:腾讯陈东东:Caelus全场景在离线混部的思考与实践

  • 关注:供应商滥用“云原生”标签,客户表示并不care
    关注:供应商滥用“云原生”标签,客户表示并不care

  • 中国高铁今日装船出海 首次出口国外用于印尼雅万高铁建设工作
    中国高铁今日装船出海 首次出口国外用于印尼雅万高铁建设工作

  • 中国长征系列火箭创下新纪录:2030年左右载人登月
    中国长征系列火箭创下新纪录:2030年左右载人登月

  • 2022未来科学大奖获奖名单公布 李文辉、杨学明、莫毅明获奖
    2022未来科学大奖获奖名单公布 李文辉、杨学明、莫毅明获奖

  • 梦天实验舱10月择机发射!“T”字构型空间站来了
    梦天实验舱10月择机发射!“T”字构型空间站来了

  • 世界头条:苹果曝出严重安全漏洞,黑客可全面接管设备!!!
    世界头条:苹果曝出严重安全漏洞,黑客可全面接管设备!!!

  • 【新视野】你以为的推荐系统,其实只是推荐模型
    【新视野】你以为的推荐系统,其实只是推荐模型

  • 环球快看:开发者驱动的软件公司,如何赚取万亿美元?
    环球快看:开发者驱动的软件公司,如何赚取万亿美元?

  • 【世界时快讯】阿里云冯诗淳:ACK容器服务生产及可观测体系的建设与实践
    【世界时快讯】阿里云冯诗淳:ACK容器服务生产及可观测体系的建设与实践

  • 观热点:使用线程池的10个坑
    观热点:使用线程池的10个坑

  • 环球热资讯!一文弄懂numpy数组
    环球热资讯!一文弄懂numpy数组

  • 焦点播报:谐云产品总监高家祺:企业级Spring Cloud Gateway网关优化实践
    焦点播报:谐云产品总监高家祺:企业级Spring Cloud Gateway网关优化实践

  • 环球滚动:网易数帆陈谔:低代码平台,应对企业应用开发复杂性的一剂良方
    环球滚动:网易数帆陈谔:低代码平台,应对企业应用开发复杂性的一剂良方

  • 每日讯息!OpenMLDB + OneFlow:手把手教你快速链接特征工程到模型训练
    每日讯息!OpenMLDB + OneFlow:手把手教你快速链接特征工程到模型训练

  • 世界观速讯丨重磅升级!TDengine3.0正式发布
    世界观速讯丨重磅升级!TDengine3.0正式发布

  • 环球播报:一块GPU训练TB级推荐模型不是梦,OneEmbedding性能一骑绝尘
    环球播报:一块GPU训练TB级推荐模型不是梦,OneEmbedding性能一骑绝尘

  • 环球新资讯:下秒数据CEO蔡致暖:云原生时代数据管道的迭代之路
    环球新资讯:下秒数据CEO蔡致暖:云原生时代数据管道的迭代之路

  • 当前快看:PyCharm 2022.2 发布了,支持最新 Python 3.11 和 PyScript 框架!
    当前快看:PyCharm 2022.2 发布了,支持最新 Python 3.11 和 PyScript 框架!

  • 速读:GPU加速Pinterest推荐模型,参数量增加100倍,用户活跃度提高16%
    速读:GPU加速Pinterest推荐模型,参数量增加100倍,用户活跃度提高16%

  • 全球微速讯:中国信通院魏博锴:云原生混部标准解读
    全球微速讯:中国信通院魏博锴:云原生混部标准解读

  • 视焦点讯!OceanBase 4.0 发布!看世界上最小的鱼如何游出一大步
    视焦点讯!OceanBase 4.0 发布!看世界上最小的鱼如何游出一大步

  • 视焦点讯!OneFlow源码解析:算子指令在虚拟机中的执行
    视焦点讯!OneFlow源码解析:算子指令在虚拟机中的执行

  • 世界快看点丨经典动画《大闹天宫》4K 版上映,老动画是如何修复的?
    世界快看点丨经典动画《大闹天宫》4K 版上映,老动画是如何修复的?

  • 环球实时:想玩转监控神器Prometheus吗?
    环球实时:想玩转监控神器Prometheus吗?

  • 新动态:腾讯云宋翔:Kubernetes集群利用率提升实践
    新动态:腾讯云宋翔:Kubernetes集群利用率提升实践

  • 中国空间站将再添新房间:梦天实验舱已运抵发射场
    中国空间站将再添新房间:梦天实验舱已运抵发射场

  • 【天天聚看点】下班后用微信处理工作时发病身亡,法院判决:工伤!
    【天天聚看点】下班后用微信处理工作时发病身亡,法院判决:工伤!

  • 每日看点!史上最猛“员工”,疯狂吐槽亿万富翁老板小扎:那么有钱,还总穿着同样的衣服!
    每日看点!史上最猛“员工”,疯狂吐槽亿万富翁老板小扎:那么有钱,还总穿着同样的衣服!

  • 天天热议:关于eBPF与可观测性,你想知道的都在这里
    天天热议:关于eBPF与可观测性,你想知道的都在这里

  • 热推荐:2022 全球 AI 模型周报
    热推荐:2022 全球 AI 模型周报

  • 当前消息!左益豪:用代码创造一个新世界|OneFlow U
    当前消息!左益豪:用代码创造一个新世界|OneFlow U

  • 全球球精选!腾讯云胡启明:Kubernetes云上资源的分析与优化
    全球球精选!腾讯云胡启明:Kubernetes云上资源的分析与优化

  • 【天天报资讯】JPEG公布智能图像编码提案结果,火山引擎排名主观质量评测第一
    【天天报资讯】JPEG公布智能图像编码提案结果,火山引擎排名主观质量评测第一

  • 快报:腾讯云孟凡杰:我所经历的云原生降本增效最佳实践案例
    快报:腾讯云孟凡杰:我所经历的云原生降本增效最佳实践案例

  • 焦点热文:SphereEx苗立尧:云原生架构下的Database Mesh研发实践
    焦点热文:SphereEx苗立尧:云原生架构下的Database Mesh研发实践

  • 世界通讯!1000 行输入框的养成:如何平衡体验与灵活性?
    世界通讯!1000 行输入框的养成:如何平衡体验与灵活性?

  • 我国攻克时速600公里高速磁浮关健技术:填补高铁、飞机之间空白
    我国攻克时速600公里高速磁浮关健技术:填补高铁、飞机之间空白

  • 全球速看:百度智能云章淼:详解企业级七层负载均衡开源软件BFE
    全球速看:百度智能云章淼:详解企业级七层负载均衡开源软件BFE

  • 世界快资讯丨华东师范大学副校长周傲英:数据赋能,从数据库到数据中台
    世界快资讯丨华东师范大学副校长周傲英:数据赋能,从数据库到数据中台

  • 每日快讯!18张图,直观理解为什么神经网络这么有效?
    每日快讯!18张图,直观理解为什么神经网络这么有效?

  • 报道:CNCF Keith Chan:分布式云时代,云原生社区的发展与趋势
    报道:CNCF Keith Chan:分布式云时代,云原生社区的发展与趋势

  • 环球热点!中国信通院陈屹力:降本增效是企业云原生应用的最大价值
    环球热点!中国信通院陈屹力:降本增效是企业云原生应用的最大价值

  • 看热讯:一种分布式深度学习编程新范式:Global Tensor
    看热讯:一种分布式深度学习编程新范式:Global Tensor

  • 环球观点:一网打尽:Spring Cloud最新技术与实践
    环球观点:一网打尽:Spring Cloud最新技术与实践

  • 视讯!微软默默给 curl 捐赠一万美元,半年后才通知
    视讯!微软默默给 curl 捐赠一万美元,半年后才通知

  • 我国首条跨海高铁福厦高铁桥梁主体工程全线贯通 预计明年下半年运行
    我国首条跨海高铁福厦高铁桥梁主体工程全线贯通 预计明年下半年运行

  • 探索生命起源等领域 中国空间站科学实验设施还有这些神奇功能
    探索生命起源等领域 中国空间站科学实验设施还有这些神奇功能

  • 环球今亮点!RTC 性能自动化工具在内存优化场景下的实践
    环球今亮点!RTC 性能自动化工具在内存优化场景下的实践

  • 全球今头条!如何在OneFlow中新增算子
    全球今头条!如何在OneFlow中新增算子

  • 世界最大单口径射电望远镜:中国天眼已发现660多颗新脉冲星
    世界最大单口径射电望远镜:中国天眼已发现660多颗新脉冲星

  • 环球热议:图像处理解决方案 veImageX 技术演进之路
    环球热议:图像处理解决方案 veImageX 技术演进之路

  • “问海1号”6000米级自主遥控水下机器人正式交付 具备大范围自主巡航探测和定点精细遥控取样作业功能
    “问海1号”6000米级自主遥控水下机器人正式交付 具备大范围自主巡航探测和定点精细遥控取样作业功能

  • 播报:伙伴云戴志康:如何利用低代码提升研发和IT效能
    播报:伙伴云戴志康:如何利用低代码提升研发和IT效能

  • 今日热搜:OneFlow v0.8.0正式发布
    今日热搜:OneFlow v0.8.0正式发布

  • 焦点信息:Kyligence李栋:从数据湖到指标中台,提升数据分析ROI
    焦点信息:Kyligence李栋:从数据湖到指标中台,提升数据分析ROI

  • 焦点热讯:大模型训练难于上青天?效率超群、易用的“李白”模型库来了
    焦点热讯:大模型训练难于上青天?效率超群、易用的“李白”模型库来了

  • 问天实验舱与火箭组合体转运至发射区 发射前准备进入“最后一公里”
    问天实验舱与火箭组合体转运至发射区 发射前准备进入“最后一公里”

  • 中国空间站的光学舱:巡天空间望远镜预计2024年投入科学运行
    中国空间站的光学舱:巡天空间望远镜预计2024年投入科学运行

  • 全球快播:基于 SPICE 协议的硬编推流整合方案在云游戏中的应用
    全球快播:基于 SPICE 协议的硬编推流整合方案在云游戏中的应用

  • 微头条丨现代数据栈:高效开发数据,辅助企业决策
    微头条丨现代数据栈:高效开发数据,辅助企业决策

  • 【天天时快讯】开源实时数仓 Apache Doris 毕业了,未来如何走得更远?
    【天天时快讯】开源实时数仓 Apache Doris 毕业了,未来如何走得更远?

  • 世界观焦点:防止员工泄密?深圳一公司给每个工位都安装监控
    世界观焦点:防止员工泄密?深圳一公司给每个工位都安装监控

  • 热文:实时互动还有哪些可能?RTE 2022 创新编程挑战赛正式开启
    热文:实时互动还有哪些可能?RTE 2022 创新编程挑战赛正式开启

  • 全球观天下!WPS被曝删除用户本地文件,官方两度回应:不会侵犯用户隐私
    全球观天下!WPS被曝删除用户本地文件,官方两度回应:不会侵犯用户隐私

  • 长三乙成功发射天链二号03星 天地通话、太空授课、出舱活动都离不开它
    长三乙成功发射天链二号03星 天地通话、太空授课、出舱活动都离不开它

  • 热门:Apache Flink ML 2.1.0 发布公告
    热门:Apache Flink ML 2.1.0 发布公告

  • 当前聚焦:【7月12日活动预告】现代数据栈峰会
    当前聚焦:【7月12日活动预告】现代数据栈峰会

  • 中国首颗综合性太阳探测专用卫星10月发射 重888kg
    中国首颗综合性太阳探测专用卫星10月发射 重888kg

  • 焦点信息:阿里云杨皓然:Serverless或将引领云的下一个时代
    焦点信息:阿里云杨皓然:Serverless或将引领云的下一个时代

  • 全球即时看!阿里巴巴余军:钉钉宜搭低代码实践之路
    全球即时看!阿里巴巴余军:钉钉宜搭低代码实践之路

  • 热门看点:LLVM之父Chris Lattner:为什么我们要重建AI基础设施软件
    热门看点:LLVM之父Chris Lattner:为什么我们要重建AI基础设施软件

  • 全球头条:基于http-flv的抖音直播端到端延迟优化实践
    全球头条:基于http-flv的抖音直播端到端延迟优化实践

  • 天天新动态:拼多多败诉:砍价始终差0.9%侵犯知情权,被判赔400元
    天天新动态:拼多多败诉:砍价始终差0.9%侵犯知情权,被判赔400元

  • 滚动:Flink:企业向实时化、智能化大数据计算转型的利器
    滚动:Flink:企业向实时化、智能化大数据计算转型的利器

  • 全球看点:比尔·盖茨晒48年前简历:“没你们的好看”
    全球看点:比尔·盖茨晒48年前简历:“没你们的好看”

  • 天天微速讯:31年前的Beyond演唱会,是如何超清修复的?
    天天微速讯:31年前的Beyond演唱会,是如何超清修复的?

  • 环球聚焦:偷窃他人漏洞报告变卖成副业,漏洞赏金平台出“内鬼”
    环球聚焦:偷窃他人漏洞报告变卖成副业,漏洞赏金平台出“内鬼”

  • 《模拟人生4》DLC“高中时代”中文预告公开 7月29日发售登陆多个平台
    《模拟人生4》DLC“高中时代”中文预告公开 7月29日发售登陆多个平台

  • 动态焦点:Geoffrey Hinton:我的五十年深度学习生涯与研究心法
    动态焦点:Geoffrey Hinton:我的五十年深度学习生涯与研究心法

  • 焦点播报:分析超700万个研发需求发现,这八大编程语言才是行业最需要的
    焦点播报:分析超700万个研发需求发现,这八大编程语言才是行业最需要的

  • 世界今日报丨微信表情符号写入判决书,你发的OK、炸弹都可能成为“呈堂证供”
    世界今日报丨微信表情符号写入判决书,你发的OK、炸弹都可能成为“呈堂证供”

  • 热文:OneFlow源码解析:算子签名的自动推断
    热文:OneFlow源码解析:算子签名的自动推断

  • 《全境封锁2》国服首测将至:显卡最低GTX 1060、硬盘留下90GB
    《全境封锁2》国服首测将至:显卡最低GTX 1060、硬盘留下90GB

  • 天天观察:计算机艺术和动画之父肯·诺尔顿去世,享年91岁
    天天观察:计算机艺术和动画之父肯·诺尔顿去世,享年91岁

  • 苦等将近一年腾讯《全境封锁2》国服官微终于上线 可能在晚些时候的发布会上公布新消息
    苦等将近一年腾讯《全境封锁2》国服官微终于上线 可能在晚些时候的发布会上公布新消息

  • 世界新消息丨运行近20年,基于Win 98的火星探测器软件迎来首次升级
    世界新消息丨运行近20年,基于Win 98的火星探测器软件迎来首次升级

  • 《最后的生还者:重制版》至少需要75GB硬盘空间 还将支持DualSense手柄功能
    《最后的生还者:重制版》至少需要75GB硬盘空间 还将支持DualSense手柄功能

  • 世界快看:微软警告 Windows 8.1 用户:系统即将停止支持,建议购买 Win11/10 新设备
    世界快看:微软警告 Windows 8.1 用户:系统即将停止支持,建议购买 Win11/10 新设备

  • 焦点短讯!防止被整顿?一公司招聘要求员工不能起诉公司
    焦点短讯!防止被整顿?一公司招聘要求员工不能起诉公司

  • 每日看点!图解OneFlow的学习率调整策略
    每日看点!图解OneFlow的学习率调整策略

  • 当前视点!天才制造者:独行侠、科技巨头和AI|深度学习崛起十年
    当前视点!天才制造者:独行侠、科技巨头和AI|深度学习崛起十年

  • 全球今热点:一键生成大学、专业甚至录取概率,AI填报志愿卡这么神奇?
    全球今热点:一键生成大学、专业甚至录取概率,AI填报志愿卡这么神奇?

  • 《糖豆人:终极淘汰赛》转免费游戏第一天:2小时都匹配不上玩家 官方称正紧急修复
    《糖豆人:终极淘汰赛》转免费游戏第一天:2小时都匹配不上玩家 官方称正紧急修复

  • Xbox+B社发布会上亮相的第一方游戏《极限竞速8》 在Xbox Series S上的目标是1080P/60FPS
    Xbox+B社发布会上亮相的第一方游戏《极限竞速8》 在Xbox Series S上的目标是1080P/60FPS

  • 实时:世界上第一个“半机械人”去世,改造自己只为“逆天改命”
    实时:世界上第一个“半机械人”去世,改造自己只为“逆天改命”

  • 天天资讯:深度学习概述:从基础概念、计算步骤到调优方法
    天天资讯:深度学习概述:从基础概念、计算步骤到调优方法

  • 中国建成世界首条环沙漠铁路线:官方揭秘将不可能变成可能背后有多难
    中国建成世界首条环沙漠铁路线:官方揭秘将不可能变成可能背后有多难

  • 【播资讯】从北京“润”到芝加哥,工程师宝玉“滋润”成长的秘诀
    【播资讯】从北京“润”到芝加哥,工程师宝玉“滋润”成长的秘诀

  • 【快播报】训练千亿参数大模型,离不开四种GPU并行策略
    【快播报】训练千亿参数大模型,离不开四种GPU并行策略

  • 看点:New PMC 田原: 开源给了我一个接触非业务系统的机会
    看点:New PMC 田原: 开源给了我一个接触非业务系统的机会

  • 每日视讯:一文读懂 TsFile
    每日视讯:一文读懂 TsFile

  • 经典jump系热血动漫类作品《海贼王》“和之国”篇完结 最终章7月25日启动
    经典jump系热血动漫类作品《海贼王》“和之国”篇完结 最终章7月25日启动

  • 微软Xbox游戏机诞生20周年纪录片获艾美奖 记录了该主机多项不为人知的过去
    微软Xbox游戏机诞生20周年纪录片获艾美奖 记录了该主机多项不为人知的过去

  • IGN评有史以来最好看的12部惊悚片 希区柯克多部作品榜上有名
    IGN评有史以来最好看的12部惊悚片 希区柯克多部作品榜上有名

  • 甩开暑期档第二名4.7亿:系列收官之作《侏罗纪世界3》内地票房突破6亿大关
    甩开暑期档第二名4.7亿:系列收官之作《侏罗纪世界3》内地票房突破6亿大关

  • 同名漫画作品改编动画《终末的女武神》第二季动画公布新视觉图 2023年上线网飞
    同名漫画作品改编动画《终末的女武神》第二季动画公布新视觉图 2023年上线网飞

  • 经典电影《回到未来》未开封录像带拍出近8万美元新高价 成未开封VHS录像带拍出的的史上最高价
    经典电影《回到未来》未开封录像带拍出近8万美元新高价 成未开封VHS录像带拍出的的史上最高价

  • Netflix漫画改编作品悬疑电视剧《今际之国的爱丽丝》第2季新角色公开 12月上线
    Netflix漫画改编作品悬疑电视剧《今际之国的爱丽丝》第2季新角色公开 12月上线

  • 妮可·基德曼将主演惊悚片《荷兰,密歇根》 经典希区柯克式惊悚风格
    妮可·基德曼将主演惊悚片《荷兰,密歇根》 经典希区柯克式惊悚风格

  • 琼恩雪诺回归 有报道称《权力的游戏》电视剧续集制作中可能要讲述发生在原著之后的剧情
    琼恩雪诺回归 有报道称《权力的游戏》电视剧续集制作中可能要讲述发生在原著之后的剧情

  • 王晶买下吴宇森执导经典电影《纵横四海》版权 古天乐谢霆锋或将出演
    王晶买下吴宇森执导经典电影《纵横四海》版权 古天乐谢霆锋或将出演

  • 《神秘海域》电影将于7月份登陆网飞平台 由游戏作品改编上映期间票房超4亿美元
    《神秘海域》电影将于7月份登陆网飞平台 由游戏作品改编上映期间票房超4亿美元

  • 《降世神通》宣布未来计划推出3部角色主题电影 将是动画形式而非真人改编版本
    《降世神通》宣布未来计划推出3部角色主题电影 将是动画形式而非真人改编版本

  • 著名影视媒体Deadline报道称 继《阿拉丁》之后盖·里奇将导演动画《大力士》真人电影
    著名影视媒体Deadline报道称 继《阿拉丁》之后盖·里奇将导演动画《大力士》真人电影

  • 解谜冒险游戏《彼岸晴空》公布新预告 7月20日全平台发售支持简体中文
    解谜冒险游戏《彼岸晴空》公布新预告 7月20日全平台发售支持简体中文

  • 《大家一起观颜察色。在线》Steam正式发售 支持中文免费游玩可自定义玩家形象
    《大家一起观颜察色。在线》Steam正式发售 支持中文免费游玩可自定义玩家形象

  • 《木卫四协议》灵感来源于怪形受《寂静岭》《生化危机》显著影响 比死亡空间更恐怖
    《木卫四协议》灵感来源于怪形受《寂静岭》《生化危机》显著影响 比死亡空间更恐怖

  • 皮克斯动画电影《光年正传》票房不及预期 海外首周票房3460万美元
    皮克斯动画电影《光年正传》票房不及预期 海外首周票房3460万美元

  • 实时:首个原生 ARM64 Visual Studio 发布,已上线 Windows 11!
    实时:首个原生 ARM64 Visual Studio 发布,已上线 Windows 11!

  • 速看:一个算子在深度学习框架中的旅程
    速看:一个算子在深度学习框架中的旅程

  • 最新消息:让程序员崩溃的微信群消息置顶
    最新消息:让程序员崩溃的微信群消息置顶

  • 每日热闻!罗永浩宣布退出社交平台,年近半百再次埋头创业,“真还传”接近尾声
    每日热闻!罗永浩宣布退出社交平台,年近半百再次埋头创业,“真还传”接近尾声

  • 即时:谷歌研究员走火入魔事件曝光:认为AI已具备人格,被罚带薪休假,聊天记录让网友San值狂掉...
    即时:谷歌研究员走火入魔事件曝光:认为AI已具备人格,被罚带薪休假,聊天记录让网友San值狂掉...

  • 今头条!让预训练语言模型读懂数字:超对称技术联合复旦知识工场等发布10亿参数BigBang Transformer[乾元]金融大规模预训练语言模型
    今头条!让预训练语言模型读懂数字:超对称技术联合复旦知识工场等发布10亿参数BigBang Transformer[乾元]金融大规模预训练语言模型

  • 微动态丨由一亿多条仇恨言论训练后,这个AI机器人成了恶毒的“键盘侠”
    微动态丨由一亿多条仇恨言论训练后,这个AI机器人成了恶毒的“键盘侠”

  • 首幅1:250万月球全月地质图发布 为月球科学研究提供重要资料
    首幅1:250万月球全月地质图发布 为月球科学研究提供重要资料

  • 动视宣布《使命召唤》重返Steam平台 “跳弹”反作弊系统将与游戏同日发布
    动视宣布《使命召唤》重返Steam平台 “跳弹”反作弊系统将与游戏同日发布

  • 卡普空线上发布会游戏名单:《生化危机8:村庄》DLC、《街头霸王6》等
    卡普空线上发布会游戏名单:《生化危机8:村庄》DLC、《街头霸王6》等

  • 粉丝使用虚幻5引擎自制版《生化危机4》出炉 画质、光影极限加强人物动作丝滑流畅
    粉丝使用虚幻5引擎自制版《生化危机4》出炉 画质、光影极限加强人物动作丝滑流畅

  • 《LoveLive!超级明星》第二季新预告发布四名新成员加入 7月17日开播
    《LoveLive!超级明星》第二季新预告发布四名新成员加入 7月17日开播

  • 激励网络影视产业精耕细作 《网络剧片发行许可证》今日起全面发放
    激励网络影视产业精耕细作 《网络剧片发行许可证》今日起全面发放

  • WWDC 2022 现场活动的当天日程曝光 充实的库比蒂诺Apple Park一日游
    WWDC 2022 现场活动的当天日程曝光 充实的库比蒂诺Apple Park一日游

  • Reebok携手Zappos推出两款Fit to Fit自适应系列运动鞋 售65/90美元
    Reebok携手Zappos推出两款Fit to Fit自适应系列运动鞋 售65/90美元

  • 进军手机游戏领域 Take-Two127亿美元收购Zynga公司的所有工作已经完成
    进军手机游戏领域 Take-Two127亿美元收购Zynga公司的所有工作已经完成

  • 《碟中谍7:致命清算》首支中字预告发布 预计将于2023年7月上映
    《碟中谍7:致命清算》首支中字预告发布 预计将于2023年7月上映

  • 超微半导体公司CEO“苏妈”表示 今年总计会有超过200款笔记本电脑搭载AMD锐龙平台
    超微半导体公司CEO“苏妈”表示 今年总计会有超过200款笔记本电脑搭载AMD锐龙平台

  • Remedy正式公布《心灵杀手:复刻版》消息 预计将于今年秋季跨平台发售
    Remedy正式公布《心灵杀手:复刻版》消息 预计将于今年秋季跨平台发售

  • 任天堂为节奏游戏三部曲《大金刚鼓》商标续期 经典作品系列或将再次登录Switch
    任天堂为节奏游戏三部曲《大金刚鼓》商标续期 经典作品系列或将再次登录Switch

  • 世嘉CEO与CFO参加投资者问答环节:对《索尼克:边境》寄予厚望并已设定内部目标
    世嘉CEO与CFO参加投资者问答环节:对《索尼克:边境》寄予厚望并已设定内部目标

  • 美NOAA发布由GOES-18卫星拍摄的首批西半球图像 扫描地球的速度是前代卫星的五倍
    美NOAA发布由GOES-18卫星拍摄的首批西半球图像 扫描地球的速度是前代卫星的五倍

  • 全球气温很快超《巴黎协定》限值?WMO:未来5年升高可能性为50% 将引发更多极端天气
    全球气温很快超《巴黎协定》限值?WMO:未来5年升高可能性为50% 将引发更多极端天气

  • 天舟四号宇宙级“送货” 都送了啥?涵盖多个领域生活与科研需求
    天舟四号宇宙级“送货” 都送了啥?涵盖多个领域生活与科研需求

  • 中国空间站全面建造阶段揭幕之战五大看点
    中国空间站全面建造阶段揭幕之战五大看点

  • 中国打造旗舰级太空望远镜 将有助揭示宇宙演化奥秘
    中国打造旗舰级太空望远镜 将有助揭示宇宙演化奥秘

  • 祝融号”火星车准备越冬 环绕器持续开展环绕探测
    祝融号”火星车准备越冬 环绕器持续开展环绕探测

  • 不需要会员 《堡垒之夜》成Xbox云游戏首个免费游戏
    不需要会员 《堡垒之夜》成Xbox云游戏首个免费游戏

WEB开发网