vscode调试python(transformers库的llama为例)

本文参考链接如下:
transformers源码阅读------vscode调试llama模型代码

1. 调试文件

因为只是搞清楚数据的流向,所以不需要下载任何预训练的参数

python 复制代码
from transformers.models.llama import LlamaModel,LlamaConfig
import torch

def run_llama():
    # part 1  模型初始化
    llamaconfig = LlamaConfig(vocab_size=32000,
                              hidden_size=4096//2,
                              intermediate_size=11008//2,
                              num_hidden_layers=32//2,
                              num_attention_heads=32//2,
                              max_position_embeddings=2048//2)
    
    llamamodel = LlamaModel(config = llamaconfig)

    # part 2 构建输入数据,在正向传播过程中,只需要传一个inputs_ids,batchsize是4,序列长度是30,每个元素是一个(0,llamaconfig.vocab_size)的随机整数
    inputs_ids = torch.randint(
        low=0,
        high=llamaconfig.vocab_size,
        size=(4,30))
    
    # part 3
    res = llamamodel(inputs_ids)##前向计算,等价于llamamodel.forward(inputs_ids)
    print(res)


if __name__ == "__main__":
    run_llama()

2. vscode调试

2.1 设置调试配置文件

点击左侧边栏的运行和调试按钮:

然后点击创建launch.json文件

然后会出现 python文件调试当前正在运行的python文件:

然后就新建了一个launch.json调试配置文件

其中"justMyCode"表示是一个否只调试当前的文件,如果是true,就没法进入transformers的代码了,所以如果想调试进入transformers的代码,就把这个属性设置为false

2.2 设置断点

先看看怎么前向计算的。按住ctrl键,点击LlamaModel进入LlamaModel定义的源码
但是LlamaModel定义的源码很多,可以通过资源管理器的大纲标签查看LlamaModel源码文件的代码结构:

为了快速抓住重点,在LlamaAttention的forward方法打断点:

调试窗口的断点标签可以找到这个断点,直接点击可以直接定位到断点的位置。

打开要调试的代码文件,然后点击调试窗口的调试按钮

然后程序运行,在断点处停止运行。可以看到出现了调试按钮组件

在VSCode调试过程中,各操作按钮的功能如下:

  1. 继续(Continue)

    • 图标 :通常为▶️(播放按钮)。

    • 功能 :从当前暂停的位置继续执行程序,直到遇到下一个断点或程序自然结束。

    • 使用场景:当检查完当前状态的变量或逻辑后,希望程序继续运行而非逐行调试。

  2. 逐过程(Step Over)

    • 图标 :通常为⏭️(向右箭头跨越圆点)。

    • 功能 :执行当前行的代码,不进入函数内部 。若当前行包含函数调用,会直接执行完该函数,并停在下一行。

    • 示例 :在foo();这一行使用"逐过程",会直接执行foo()函数全部代码,停在foo();的下一行。

  3. 单步调试(Step Into)

    • 图标 :通常为⏬(向下箭头进入函数)。

    • 功能 :进入当前行代码中的函数调用内部 ,逐行调试函数内的逻辑。

    • 示例 :在foo();这一行使用"单步调试",会跳转到foo()函数的定义处,开始逐行执行函数内的代码。

  4. 单步跳出(Step Out)

    • 图标 :通常为⏫(向上箭头跳出函数)。

    • 功能 :执行完当前函数的剩余代码,返回到调用此函数的位置 。

    • 使用场景:在函数内部调试时,若希望快速执行完当前函数并回到调用处。

  5. 重启(Restart)

    • 图标 :通常为🔄(循环箭头)。

    • 功能 :终止当前调试会话,并重新启动程序 ,从头开始执行。

    • 注意:所有变量和状态会被重置。

  6. 停止(Stop)

    • 图标 :通常为⏹️(方块图标)。

    • 功能 :终止当前调试会话 ,结束程序运行。

    • 注意:程序会立即停止,不会执行后续代码。


对比示例 :

假设有以下代码:

javascript 复制代码
function a() {
    console.log("a");
}

function b() {
    a();          // 断点设在此行
    console.log("b");
}

b();

• 在a();行暂停时:

• 逐过程(Step Over) :执行a()但不进入其内部,直接停在console.log("b");。

• 单步调试(Step Into) :跳转到a()函数内部,停在console.log("a");。

• 若在a()函数内部使用单步跳出(Step Out) :执行完a()剩余代码,返回到console.log("b");。

总结 :

• 需要跳过函数调用时用逐过程 ,深入函数时用单步调试 ,快速退出函数用单步跳出 。

• 继续 用于恢复全局执行,重启/停止用于控制调试会话的生命周期。

变量标签可以看到程序运行到断点处的调用堆栈内 的变量的值

监视标签可以定义(通过点击+)自己想要实时监视的变量,或者变量的形状:

观察变量还有一个办法,ctrl+J可以调出下面的调试控制台:

在最下面输入想要观察的变量就会给出值。同过观察代码和中间变量:

query_states的4,16,30,128是怎么得来的:首先4是batch size,30是序列长度,这在测试代码中早就定义好了:

python 复制代码
    inputs_ids = torch.randint(
        low=0,
        high=llamaconfig.vocab_size,
        size=(4,30))

传进来的hidden_states形状是4,30,2048,而self.q_proj的形状是:2048,2048,

所以self.q_proj(hidden_states)得到的输出形状是4,30,2048, hidden_shape是4,30,-1,128,所以

self.q_proj(hidden_states).view(hidden_shape)得到的输出的形状是4,30,16,128,这就是为了多头注意力机制,其中16就是头的个数,128是每个头输出维度。transpose(1, 2)将1,2维度交换,就得到了4,16,30,128

调用堆栈标签可以看到逐层的调用过程:

相关推荐
实名上网宋凯宣13 小时前
Django
后端·python·django
如若12314 小时前
【论文复现】CoFailMed:从零复现医学图像分割的共享失败审计,含完整代码流程与科研绘图
人工智能·python
砚底藏山河16 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
视觉小萌新16 小时前
AI Class 3 · Chapter 1:变量、字符串、list/dict、if/for(python学习-小白版-有经验可跳过)
python·学习·list
薛定谔的猫-菜鸟程序员16 小时前
软件架构设计师开发资料大全(从入门到精通)
后端·python·系统架构·flask·架构设计师
Ramble_Naylor18 小时前
Rust深度解读:Send 与 Sync 的本质与线程安全边界
python·算法·rust
Allen_LVyingbo19 小时前
NVIDIA CUDA Tile 在医疗计算中的算子形式化、算法重构与内核实现
大数据·python·算法·重构·知识图谱·健康医疗·数据库架构
云和数据.ChenGuang19 小时前
Python 闭包详解:从原理到实战
linux·开发语言·人工智能·python·kubernetes
我命由我1234520 小时前
Python 实用操作 - 文件操作(打开与关闭文件、读取文件、文件写入)
java·开发语言·前端·javascript·数据库·python·java-ee
青少儿编程课堂20 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:倍增法求最近公共祖先LCA解析
c++·python·算法·bfs·信息学竞赛