当前位置:

首页 > 编程开发 > 命令式编程VS符号式编程

命令式编程VS符号式编程

命令式编程逐行执行、易调试但效率较低;符号式编程先构建计算图再编译运行,内存与计算效率更高但调试不便。混合式编程结合两者优势,支持开发时用命令式、部署时转符号式。

本文目录

    先聊聊一个很有意思的话题:写代码的时候,你是喜欢逐行执行、随时能打印中间结果那种“所见即所得”的感觉,还是更倾向于先把整个计算流程搭好,最后统一“发射”一次?这两种风格,分别对应着命令式编程(imperative style)和符号式编程(symbolic style)。它们在深度学习框架里各有拥趸,也各有长短。下面我们掰开揉碎聊聊。

    什么是 symbolic / imperative style 编程

    用过 Python 或 C++ 的人对命令式编程都不陌生——程序在运行时逐条计算,绝大部分 Python 代码都是这个路子。比如下面这段:

    import numpy as np
    a = np.ones(10)
    b = np.ones(10) * 2
    c = b * a
    d = c + 1
    

    当执行到 c = b * a 时,真正的数值计算立刻就发生了。简单直接。

    符号式编程的玩法就不太一样了。你得先“定义”一个函数——这个定义本身并不做实际计算,而是用占位符描述运算逻辑,等真正给定了输入数据再统一编译执行。上面的例子用符号式重写会是这个样子:

    A = Variable('A')
    B = Variable('B')
    C = B * A
    D = C + Constant(1)
    # compiles the function
    f = compile(D)
    d = f(A=np.ones(10), B=np.ones(10)*2)
    

    看到没?C = B * A 这一句并没有触发数值计算,它只是构建了一张计算图(也叫符号图),描述出“计算链路长什么样”。下图就是 D 对应的计算图:

    这里写图片描述

    大多数符号式程序都会显式或隐式地包含一个编译步骤,把计算图转换成可以调用的函数。上面例子中,真正的数值计算只发生在最后一行。符号式编程的一个核心特征就是:明确把“构建计算图”和“生成可执行代码”分为两个阶段。对于神经网络来说,通常就是用一张计算图来描述整个模型。

    在流行深度学习框架里,Torch、Chainer、Minerva 走的是命令式路线;Theano、CGT、TensorFlow 走的则是符号式路线。CXXNet、Caffe 这类依赖配置文件的框架,其实也可以看作是符号式的——配置文件就是计算图的定义。下面我们来对比一下两边的优劣势。

    命令式编程(imperative style programs)

    命令式编程就是一步步改变程序状态,明确输入变量,按逻辑顺序逐步运算。

    优势在于:好理解——在 Python 里写命令式代码,大部分逻辑都很直观;好调试——可以单步跟踪,随时取到所有中间变量,Python 的调试工具全都能用。

    但代价也很明显:运行可能偏慢,会重复调用函数,长时间保存中间变量值,内存占用也比较高。

    用 Python 调用命令式风格的库非常自然,写法跟普通 Python 代码一样,只是在合适的位置调用库的功能来加速。但如果用 Python 调用符号式风格的库,代码结构就会发生一些变化——比如有些循环可能就很难直接写。试着把下面这个命令式片段转换成符号式看看:

    a = 2
    b = a + 1
    d = np.zeros(10)
    for i in range(d):
        d += np.zeros(10)
    

    如果符号式 API 不支持 for 循环,这个转换就没法直接完成。你不能用写 Python 的思路去调用符号式库,而是需要利用符号 API 定义的领域特定语言(DSL)。深度学习框架通常都会提供功能强大的 DSL,让用户把神经网络转成可调用的计算图。

    说到底,命令式编程更符合人的直觉,用起来更简单——你可以在任何位置打印变量值,可以随便用流程控制和循环。但事情总有两面。

    符号式编程更加有效

    符号式编程(symbolic style programs)

    符号式编程通常在计算流程完全定义好之后才会真正执行。

    优势在于:更高效——编译时系统能拿到整个计算图,有更多空间做优化;更容易移植——符号式程序可以脱离 Python 环境,以避开解释器的性能瓶颈。

    符号式编程一般需要三个步骤:

    • 定义计算流程;
    • 把计算流程编译成可执行程序;
    • 给定输入,调用编译好的程序执行。

    由于编译时系统能“看到”完整程序,所以可以大幅优化计算——不仅减少函数调用,还能节省内存。

    TensorFlow 和 Theano 就是符号式编程的代表。

    既然命令式编程更灵活、更贴近原生语言,为什么那么多深度学习框架要选择符号式?效率是最主要的原因——内存效率和计算效率都更高。我们来看一个具体的例子:

    import numpy as np
    a = np.ones(10)
    b = np.ones(10) * 2
    c = b * a
    d = c + 1
    ...
    

    这里写图片描述

    假设每个数组元素占 8 字节,这段代码在命令式编程下需要多少内存?每一行都要分配空间,一共 4 个数组,每个 10 个元素,总共 4 × 10 × 8 = 320 字节。

    但如果我们事先知道最后只需要 d 这个结果,构建计算图的时候就可以重复利用中间变量的空间。比如用原址计算——把 b 的内存借给 c 用,c 的内存再借给 d 用——这样就能省下一半内存,只需要 2 × 10 × 8 = 160 字节。

    符号式编程的限制更多——因为只需要 d,中间量比如 c 的值就无法访问了。通过原址计算,符号式可以安全复用内存,但牺牲了对中间结果的访问。而命令式编程允许你随时访问任何中间变量——这就是灵活性的代价。

    符号式编程还能通过 算子融合(operation folding) 来优化计算。还是上面那个例子,乘法和加法可以合并成一个操作,如下图所示:

    这里写图片描述

    如果在 GPU 上跑,计算图只需要一个 kernel,省掉了一个 kernel 的开销。很多优化库(比如 Caffe / CXXNet)都会人工编码来做这种融合,从而提升计算效率。

    命令式编程没法自动做算子融合,因为你不知道中间变量以后会不会被访问到。符号式编程能拿到完整的计算图,明确哪些量以后会被访问、哪些不会,所以可以放心地做融合。

    计算图 / 符号图(computation graph / symbolic graph)

    符号式编程把计算过程抽象成一张计算图(符号图),用来描述整个计算流程。

    • 所有输入节点、运算节点、输出节点都符号化处理。
    • 通过建立输入节点到输出节点的传递闭包,从输入节点出发,沿着传递闭包完成数值计算和数据流动,直到到达输出节点。
    • 经过计算图优化,以数据流方式完成计算,节省内存,计算速度快,但不太适合调试,通常不用于通用编程语言。

    大多数符号式程序都会显式或隐式地包含编译步骤,把计算图转换成可调用的函数,在代码的最后一行才真正进行运算。也就是说,符号式程序清晰地把“定义运算图”和“编译运算”这两个步骤分割开来。

    混合式编程

    简而言之:命令式编程容易理解和调试,命令语句基本没有额外优化,按原有逻辑执行。符号式编程涉及较多嵌入和优化,不容易理解和调试,但运行速度有明显提升。

    那么问题来了——有没有可能既享受命令式的好处,又能拥有符号式的优势?

    开发者们的思路是:用户先用纯命令式编程进行开发和调试,等到需要产品级别的计算性能和部署时,再把大部分命令式程序转换成符号式程序来运行。深度学习框架 Caffe 和 MXNet 就采用了这种两种模式混合的方法,给足了选择的余地。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    GitHub Copilot模型停用后会自动替换吗,哪些事情仍需提前确认?
    GitHub Copilot模型停用后会自动替换吗,哪些事情仍需提前确认?

    Copilot停用旧模型不等于自动迁移;区分移除、组织模型启用、工作流切换与个人年订阅例外。

    GitHub Actions重跑失败作业会使用最新代码吗
    GitHub Actions重跑失败作业会使用最新代码吗

    解释已有运行重跑的提交和权限边界,给出确认、失败作业重跑及结果核对命令,区分漏触发事件。

    chat-demo v0.1.1怎么本地运行并理解DeepSeek历史数据边界
    chat-demo v0.1.1怎么本地运行并理解DeepSeek历史数据边界

    chat-demo v0.1.1可以作为静态聊天客户端在本地运行,但模型、搜索、文件和语音能力仍由DeepSeek API提供。源码运行环境为Node.js 22.12及以上、Git与pnpm。Demo版本号不等于应用API版本;这套应用API未单独标版本,默认聊天模型ID是deepseek-flash。

    GitHub Copilot CLI v1.0.111的用量图与上下文比例应该怎样理解
    GitHub Copilot CLI v1.0.111的用量图与上下文比例应该怎样理解

    理解GitHub Copilot CLI v1.0.111的高级请求百分比、用户提示活动图与实际路由模型窗口,区分显示口径和任务状态。

    n8n 2.47.6、2.47.7、2.48.3 Beta、2.48.4 Beta、3.2.2预发布与1.123.96适用哪些安全修复?
    n8n 2.47.6、2.47.7、2.48.3 Beta、2.48.4 Beta、3.2.2预发布与1.123.96适用哪些安全修复?

    按维护分支、利用权限与节点类型对应四项修复,区分正式补丁、Beta和临时缓解的适用边界。

    GitHub合并故障的已缓解、监控与已解决有什么不同
    GitHub合并故障的已缓解、监控与已解决有什么不同

    GitHub合并故障中的“已缓解并监控”和“已解决”不能互换。前者表示影响已经采取措施缓解,仍在观察稳定性;后者是供应商正式结束这场事故的状态。11月13日的Pull Requests合并超时事件先进入监控,随后于北京时间11月14日02:29标记为已解决。

    llama.cpp v1.0.0的网页聊天分组与Markdown编辑适合哪些场景
    llama.cpp v1.0.0的网页聊天分组与Markdown编辑适合哪些场景

    llama.cpp v1.0.0改善聊天组织、长消息编辑和附件预览;界面变化与底层API迁移、缓存及访问边界需要分别理解。

    Postman 12.36.4 更新后仍报错,怎么判断是哪一层的问题
    Postman 12.36.4 更新后仍报错,怎么判断是哪一层的问题

    Postman 12.36.4 更新后仍有异常时,可按应用、API请求和平台服务区分问题范围,避免把补丁版本当作故障原因。

    n8n 2.47.6、2.48.3 Beta与1.123.96适合哪些部署环境?
    n8n 2.47.6、2.48.3 Beta与1.123.96适合哪些部署环境?

    按正式、预发布和1.x维护渠道对应补丁,再结合Redis、Agent端点和Pinecone索引判断适用范围。

    Codex CLI 0.169.0与0.171.0-alpha.2怎样选择,终端工作区适合哪些任务
    Codex CLI 0.169.0与0.171.0-alpha.2怎样选择,终端工作区适合哪些任务

    Codex CLI 0.169.0提供有明确说明的终端工作区能力;0.171.0-alpha.2为预发布,当前没有功能清单,选用时应分开评估。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。