系统调优助手,PyTorch Profiler TensorBoard 插件教程

0x1. 前言

使用PyTorch Profiler进行性能分析已经一段时间了,毕竟是PyTorch提供的原生profile工具,个人感觉做系统性能分析时感觉比Nsys更方便一些,并且画的图也比较直观。这里翻译一下PyTorch Profiler TensorBoard Plugin的教程并分享一些使用经验,我使用的时候也是按照这个教程来来的,有一点不一样的是可以在vscode里面直接安装TensorBoard插件,然后Command+Shift+P打开vscode的命令行窗口输入TensorBoard启用TensorBoard插件并把PyTorch Profiler输出的日志文件所在的文件夹路径传给它就可以直接在vscode里面查看可视化Profile结果了。

如果有时候出现下面这种TensorBoard启动超时的情况可以手动杀掉vscode里和tensorboard相关的进程,比如在linux上:pkill -f tensorboard

在这里插入图片描述

https://github.com/pytorch/kineto/blob/main/tb_plugin/examples/resnet50_profiler_api.py 和 https://github.com/pytorch/kineto/blob/main/tb_plugin/examples/resnet50_ddp_profiler.py 分别给出了单机和多机的ResNet50模型profile脚本,核心就是下面2个红框部分。

在这里插入图片描述

然后,我日常是使用 tensorboard --logdir=./samples --bind_all 这条命令来把可视化结果映射到本地浏览器里面(通过打开:http://localhost:6006/#pytorch_profiler )。然后我们也要利用好悬浮工具栏,也就是下面红色框部分,当我们点了第三个按钮之后可以通过你可以通过向上拖动鼠标并按住鼠标左键来放大。这个按钮是最常用的。
在这里插入图片描述

另外,在可视化界面的右上角有一个Flow Events按钮,有ac2g和fwdbwd两个按钮,前面这个按钮可以让我们获得CPU算子和CUDAKernel的映射关系。比如下图有一个aten::gt算子:

在这里插入图片描述

在这里插入图片描述

我们可以看到它对应了一个cuda的elementwise算子。

总之很强就是了,相比Nsight System可以直接看到一些分析结果。并且Trace功能非常有用,而Nsight System得肉眼去定位。

除了做训练系统的分析之外,PyTorch Profiler 同样可以用在单个算子或者推理的模型中。

我之后打算聊一些Megatron-LM的细节,其中重要的依据就是使用PyTorch Profiler 的结果,所以这里对PyTorch Profiler TensorBoard Plugin教程做一个翻译,利好初次使用的读者。

最后唠叨一句,PyTorch Profiler在渲染很大的网络的Trace图时需要的时间可能会比较久,以LLama7b为例,为了避免这个问题你可以控制Profile的step为1或者减少Transformer Block的层数为原始的1/4,这样就能很快的得到Trace视图了。如果有需要可以继续浏览0x2节的翻译,或者作为查阅的参考资料。

0x2. 翻译

PyTorch Profiler TensorBoard Plugin 教程地址见:https://github.com/pytorch/kineto/blob/main/tb_plugin/README.md

这是一个用于可视化 PyTorch 性能分析的 TensorBoard 插件。它可以解析、处理并可视化 PyTorch Profiler 导出的性能分析结果,并提供优化建议。

快速安装指南

  • 从 pypi 安装

    pip install torch-tb-profiler

    若要安装支持 S3 / AzureBlob / GCS / HDFS 扩展的版本,请使用 pip install torch-tb-profiler[s3/blob/gs/hdfs],例如 pip install torch-tb-profiler[s3]

  • 或者你可以从源代码安装

    克隆 git 仓库:

    git clone https://github.com/pytorch/kineto.git

    导航到 kineto/tb_plugin 目录。

    使用以下命令安装:

    pip install .

  • 构建wheel文件

    • python setup.py build_fe sdist bdist_wheel
      注意:build_fe步骤需要设置 yarn 和 Node.js
    • python setup.py sdist bdist_wheel

快速启动指南

  • 准备性能分析数据

    我们已经准备了一些样本性能分析数据在 kineto/tb_plugin/samples(./samples)
    你可以直接下载。
    或者你可以通过运行 kineto/tb_plugin/examples/resnet50_profiler_api.py(./examples/resnet50_profiler_api.py) 来生成这些样本数据。
    你还可以从 PyTorch Profiler(https://pytorch.org/tutorials/intermediate/tensorboard_profiler_tutorial.html?highlight=tensorboard) 学习如何对你的模型进行性能分析并生成性能分析数据。

    注意:推荐的生成性能分析数据的方法是在创建 torch.profiler.profile 时,将 torch.profiler.tensorboard_trace_handler 分配给 on_trace_ready

  • 启动 TensorBoard

    在 TensorBoard 中指定性能分析数据文件夹为 logdir。如果使用上述样本数据,启动 TensorBoard 命令为:

    tensorboard --logdir=./samples

    如果你的网络浏览器不在启动 TensorBoard 的同一台机器上,你可以添加 --bind_all 选项,如:

    tensorboard --logdir=./samples --bind_all

    注意:确保默认端口 6006 对浏览器的主机开放。

  • 在 Chrome 浏览器中打开 TensorBoard

    在浏览器中打开 URL http://localhost:6006
    如果你在启动 tensorboard 命令中使用了 --bind_all,主机名可能不是 ‘localhost’。你可能会在命令后打印的日志中找到它。

  • 导航到 PYTORCH_PROFILER 标签页

    如果 --logdir 下的文件太大或太多,请稍等一会儿并刷新浏览器以查看最新加载的结果。

  • 从云端加载性能分析数据
    这一堆就不翻译了,基本很难用到,感兴趣的可以查看原文。

快速使用指南

我们将每次启用分析器的运行视为一个“运行”。
在大多数情况下,一个运行是一个单独的进程。如果启用了分布式数据并行(DDP),那么一个运行将包括多个进程。
我们将每个进程称为一个“工作节点”。

每个运行对应于由 “–logdir” 指定的文件夹下的一个子文件夹。
每个子文件夹包含一个或多个 chrome 跟踪文件,每个进程一个。
kineto/tb_plugin/samples 是文件组织方式的一个示例。

在这里插入图片描述

你可以在TensorBoard左侧控制面板上选择运行的工作节点。

在这里插入图片描述

Runs:选择一个运行。每个运行是一次启用性能分析的 PyTorch 应用程序执行。

Views:我们将性能分析结果组织成多个视图,从粗粒度(概览级别)到细粒度(kernel级别)。

Workers:选择一个工作节点。每个工作节点是一个进程。在使用 DDP 时可能有多个工作节点。

Spans:使用 torch.profiler.schedule(https://github.com/pytorch/pytorch/blob/master/torch/profiler/profiler.py#L24) 作为 torch.profiler 的schedule,可能会生成不同跨度的多个性能跟踪文件。你可以用这个选择框选择它们。

目前我们有以下性能诊断视图:

  • 总览视图
  • 操作符视图
  • kernel 视图
  • 跟踪视图
  • 内存视图
  • 分布式视图

我们将在下面描述每个视图。

  • 总览视图

总览视图是你性能分析运行中过程的顶级视图。
它显示了包括主机和 GPU 设备在内的时间成本概览。
你可以在左侧面板的“工作节点”下拉菜单中选择当前工作节点。

总览视图的一个示例:

在这里插入图片描述

‘GPU Summary’ 面板显示了此次运行的 GPU 信息和使用指标,包括名称、全局内存、计算能力等。
‘GPU Utilization’、‘Est. SM Efficiency’ 和 ‘Est. Achieved Occupancy’ 显示了此次运行在不同级别的 GPU 使用效率。
‘Kernel Time using Tensor Cores’ 显示了 Tensor Core kernel激活的时间百分比。
以上四个指标的详细信息可以在 gpu_utilization(./docs/gpu_utilization.md) 中找到。

‘Step Time Breakdown’ 面板显示了性能概要。我们将每次迭代(通常是一个小批量)视为一个step。
每个步骤花费的时间分为以下几类:

  1. kernel :GPU 设备上的kernel 执行时间;

  2. Memcpy:涉及 GPU 的内存复制时间(D2D、D2H 或 H2D);

  3. Memset:涉及 GPU 的内存设置时间;

  4. 通信:仅在 DDP 情况下出现的通信时间;

  5. 运行时:主机端的 CUDA 运行时执行时间;
    例如 cudaLaunchKernel、cudaMemcpyAsync、cudaStreamSynchronize 等;

  6. DataLoader:在 PyTorch DataLoader 对象中的数据加载时间;

  7. CPU 执行:主机计算时间,包括每个 PyTorch 操作符的运行时间;

  8. 其他:未包含在上述任何类别中的时间。

注意:以上所有类别的总结是端到端的实际时间。

上述列表按优先级从高到低排列。我们按优先顺序计算时间。最高优先级类别(Kernel)的时间成本最先计算

,然后是 Memcpy,然后是 Memset,…,最后是其他。在以下示例中,“kernel ”首先被计为 7-2=5 秒;然后“Memcpy”被计为 0 秒,因为它完全被“Kernel”掩盖;然后“CPU 执行”被计为 2-1=1 秒,因为 [2,3] 时间间隔被“kernel ”掩盖,只有 [1,2] 时间间隔被计算。通过这种方式,一个step中所有 7 类别计算的时间总和将与该step的总实际时间相同。

在这里插入图片描述

  • Operator视图

此视图显示了在主机或设备上执行的每个 PyTorch 操作符的性能。

在这里插入图片描述

每个表格行都是一个 PyTorch 操作符,这是由 C++ 实现的计算操作符,例如 “aten::relu_”、“aten::convolution”。

调用次数:此运行中操作符被调用的次数。

设备自身持续时间:在 GPU 上累计花费的时间,不包括此操作符的子操作符。

设备总持续时间:在 GPU 上累计花费的时间,包括此操作符的子操作符。

主机自身持续时间:在主机上累计花费的时间,不包括此操作符的子操作符。

主机总持续时间:在主机上累计花费的时间,包括此操作符的子操作符。

Tensor Core适用性:此操作符是否适用于使用Tensor Core。

Tensor Core自身百分比:使用Tensor Core的自身kernel时间 / 自身kernel时间。
自身kernel不包括由此操作符的子操作符启动的kernel。

Tensor Core总百分比:使用Tensor Core的kernel时间 / kernel时间。

调用栈:如果已在性能分析跟踪文件中记录,则显示此操作符的所有调用栈。
要转储此调用栈信息,应在 torch.profiler API 中设置 ‘with_stack’ 参数。
如果在 VSCode 中启动 TensorBoard,点击此调用栈会转到源代码的相应行,如下图:

在这里插入图片描述

注意:上述每个持续时间都表示实际时间。这并不意味着在此期间 GPU 或 CPU 完全被利用。

前四个饼图是上述四列持续时间的可视化。它们使得细分在一瞥间就可见。饼图中将仅显示按持续时间排序的前 N 个操作符(在文本框中可配置)。

搜索框允许按名称搜索操作符。

“分组依据”可以选择“操作符”和“操作符 + 输入形状”。
“输入形状”是此操作符输入参数列表中的张量形状。
空的“[]”表示具有标量类型的参数。
例如,“[[32, 256, 14, 14], [1024, 256, 1, 1], [], [], [], [], [], [], []]”
表示此操作符有 9 个输入参数,
第一个是尺寸为 32*256*14*14 的张量,
第二个是尺寸为 1024*256*1*1 的张量,
接下来的七个是标量变量。

在这里插入图片描述

性能建议:利用性能分析结果自动突出可能的瓶颈,并给用户提供可行的优化建议。

  • kernel 视图

此视图显示在 GPU 上所有kernel 的时间花费。时间通过减去kernel 的开始时间和结束时间来计算。

注意:此视图不包括 cudaMemcpy 或 cudaMemset。因为它们不是kernel 。

在这里插入图片描述

Tensor Core使用情况:此kernel 是否使用Tensor Core。

总持续时间:此kernel 所有调用的累计时间。

平均持续时间:所有调用的平均时间持续。即“总持续时间”除以“调用次数”。

最大持续时间:所有调用中的最长时间持续。

最小持续时间:所有调用中的最短时间持续。

注意:这些持续时间只包括 GPU 设备上kernel 的经过时间。这并不意味着 GPU 在此时间间隔内忙于执行指令。由于诸如内存访问延迟或并行度不足等原因,一些 GPU 核心可能处于空闲状态。
例如,每个 SM 可用的 warps 数量可能不足以有效地隐藏内存访问延迟,或者一些 SM 可能因为块数量不足而完全空闲。请参阅 Nvidia 的最佳实践指南(https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html)。为了研究每个kernel 的效率,我们计算并显示了最后两列的’Mean Blocks Per SM’ 和 ‘Mean Est. Achieved Occupancy’ 。

Mean Blocks Per SM:每个 SM 的Block数 = 此kernel的块数 / 此 GPU 的 SM 数量。如果这个数字小于 1,表明 GPU 多处理器未被充分利用。“平均每 SM 块数” 是使用每次运行的持续时间作为权重的所有此kernel名称运行的加权平均值。

Mean Est. Achieved Occupancy:估计实现占用率的定义可以参考 gpu_utilization(https://github.com/pytorch/kineto/blob/main/tb_plugin/docs/gpu_utilization.md),它是使用每次运行的持续时间作为权重的所有此kernel名称运行的加权平均值。

左上角的饼图是“总持续时间”列的可视化。它使得细分在一瞥间就可见。饼图中将仅显示按累计时间排序的前 N 个kernel(在文本框中可配置)。右上角的饼图是使用和未使用Tensor Core的kernel时间百分比。搜索框允许按名称搜索kernel。“分组依据”可以选择“kernel名称”和“kernel属性 + 操作符名称”。“内kernel名称”将按kernel名称分组kernel。“kernel属性 + 操作符名称”将按kernel名称、启动操作符名称、网格、块、每线程寄存器数和共享内存的组合分组kernel。

在这里插入图片描述

  • 跟踪视图

此视图使用 chrome 跟踪插件显示时间线。每个水平区域代表一个线程或一个 CUDA 流。
每个彩色矩形代表一个操作符、一个 CUDA 运行时或在 GPU 上执行的 GPU 操作
(如kernel、CUDA 内存复制、CUDA 内存设置等)

在这里插入图片描述

在上述示例中:

“thread 25772”是执行神经网络“反向”操作的 CPU 线程。

“thread 25738”是主 CPU 线程,主要进行数据加载、神经网络的前向操作和模型更新。

“stream 7”是一个 CUDA stream,显示此stream的所有kernel。

你可以看到在“线程 1”的顶部有 6 个“ProfilerStep”。每个“ProfilerStep”代表一个小批量步骤。

在这里插入图片描述

悬浮工具栏具有帮助查看跟踪线的功能。例如,当启用上下箭头时,你可以通过向上拖动鼠标并按住鼠标左键来放大。

在这里插入图片描述

“Optimizer.step#SGD.step”和“enumerate(DataLoader)#_SingleProcessDataLoaderIter.next”
是高级 Python 端函数。

当你在右上角选择“流事件”为“异步”时,你可以看到操作符及其启动的kernel之间的关系。

在这里插入图片描述

你还可以在跟踪视图中查看 GPU 利用率和估计的 SM 效率。它们沿着时间线绘制:

在这里插入图片描述

当你在右上角选择“Flow events”为“fwd_bwd_correlation”时,你可以看到前向操作符及其启动的反向操作符之间的关系。注意:只有直接启动的反向操作符的前向操作符将通过线连接,调用此操作符为子操作符的祖先操作符不会被连接。

在这里插入图片描述

  • 内存视图

Pytorch 分析器记录了分析期间的所有内存分配/释放事件和分配器的内部状态。对于每个操作符,插件会聚合其生命周期内的所有事件。

在这里插入图片描述

内存种类可以在“设备”选择框中选择。例如,“GPU0”表示接下来的图表和表格只显示每个操作符在 GPU 0 上的内存使用情况,不包括 CPU 或其他 GPU。

  • 内存曲线

内存曲线显示了内存使用趋势。它帮助用户了解内存消耗的概览。“已分配”曲线是从分配器请求的总内存,例如,由张量使用的内存。“保留”曲线只在底层分配器使用缓存机制时有意义。它代表分配器从操作系统分配的总内存。

用户可以在内存曲线图上选择并通过按下左键并在曲线上拖动来放大选定范围。右键单击将重置图表到初始状态。选择将影响下文提到的“内存事件”表和“内存统计”表。

  • 内存事件

    内存事件表显示内存分配和释放事件对。表中每个字段的定义:

    • 操作符:导致从分配器进行分配的直接操作符。在 Pytorch 中,一些操作符如 aten::empty 常用作张量创建的 API,在这种情况下,我们显示为 <parent-op> (<op>)

    • 大小:分配的内存大小。

      • 分配时间:相对于分析器启动的内存分配时间点。如果分配事件不包括在选定范围内,则可能从表中缺失。

      • 释放时间:相对于分析器启动的内存释放时间点。如果释放事件不包括在选定范围内,则可能从表中缺失。注意,释放的内存块可能仍被底层分配器缓存。

      • 持续时间:分配内存的生命周期。如果缺少分配时间或释放时间,则可能从表中缺失。

    • 内存统计

表中每个字段的定义:

  • 调用次数:此操作符在此运行中被调用的次数。

  • 增加的大小:包括所有子操作符的内存增加大小。它将所有分配的字节总和减去所有释放的内存字节。

  • 自身增加的大小:与操作符本身相关的内存增加大小,不包括其子操作符。它将所有分配的字节总和减去所有释放的内存字节。

  • 分配次数:包括所有子操作符的分配次数。

  • 自身分配次数:仅属于操作符本身的分配次数,不包括其子操作符。

  • 分配大小:包括所有子操作符的分配大小。它将所有分配的字节总和,不考虑内存释放。

  • 自身分配大小:仅属于操作符本身的分配大小。它将所有分配的字节总和,不考虑内存释放。

  • 分布式视图

此视图仅在使用 nccl 进行通信的 DDP 作业中自动出现。此视图中有四个面板:

在这里插入图片描述

  • 顶部面板显示此作业的节点/进程/GPU层次结构的信息。

  • 中间左侧面板是“计算/通信概览”。每个图例的定义:

    • 计算:GPU上kernel时间的总和减去重叠时间。
    • 重叠:计算和通信的重叠时间。更多的重叠代表计算和通信之间更好的并行性。理想情况下,通信将完全与计算重叠。
    • 通信:总通信时间减去重叠时间。
    • 其它:步骤时间减去计算和通信时间。可能包括初始化、数据加载、CPU计算等。

从这个视图中,你可以了解每个工作节点的计算到通信比率和工作节点之间的负载平衡。例如,如果一个工作节点的计算+重叠时间远大于其他节点,可能存在负载平衡问题,或者这个工作节点可能是一个落后者。

中间右侧面板是“同步/通信概览”。每个图例的定义:

  • 数据传输时间:总通信时间中用于实际数据交换的部分。
  • 同步时间:总通信时间中用于等待和与其他工作节点同步的部分。

从这个视图中,你可以了解通信的效率(总通信时间中实际用于交换数据的比例有多少,以及有多少时间只是等待其他工作节点的数据)

  • “Communication Operations Stats”总结了每个工作节点中所有通信操作的详细统计信息。每个字段的定义:

    • 调用次数:此操作符在此运行中被调用的次数。
    • 总大小(字节):此类型操作符中传输的总数据大小。
    • 平均大小(字节):此类型操作符中每次操作传输的平均数据大小。
    • 总延迟(微秒):此类型操作符的总延迟。
    • 平均延迟(微秒):此类型操作符的平均延迟。
    • 数据传输时间(微秒):此类型操作符的实际数据传输总时间。
    • 平均数据传输时间(微秒):此类型操作符的实际数据传输平均时间。
  • 模块视图
    如果 torch.nn.Module 信息被 Pytorch 分析器导出到结果的 Chrome 跟踪文件中,插件可以显示 nn.Module 的层次结构和摘要。
    在这里插入图片描述

  • 顶部表格显示了每个 torch.nn.Module 的统计信息,包括:

    • 出现次数:模块在训练过程中被调用的次数。
    • 操作符:模块调用的操作符数量。
    • 主机总时间:在主机上花费的累积时间,包括子模块。
    • 主机自身时间:在主机上花费的累积时间,不包括子模块。
    • 设备总时间:包含在模块中的操作符在 GPU 上花费的累积时间,包括子模块。
    • 设备自身时间:包含在模块中的操作符在 GPU 上花费的累积时间,不包括子模块。
    • 中间的火焰图显示了 torch.nn.Module 的层次结构信息。

底部图表显示了主线程操作符树。

0x3. PyTorch Profiler涉及的GPU利用率指标说明

主要涉及到 GPU Utilization,Est. SM Efficiency,Est. Achieved Occupancy,Kernel Time using Tensor Cores 这几个概念。文档:https://github.com/pytorch/kineto/blob/main/tb_plugin/docs/gpu_utilization.md

  • GPU Utilization:GPU 繁忙时间 / 所有步骤时间。数值越高越好。所有步骤时间是所有分析步骤(或称为迭代)的总时间。
    GPU 繁忙时间是在“所有步骤时间”中至少有一个 GPU kernel在此 GPU 上运行的时间。
    然而,这个高级别的利用率指标是粗糙的。它不能显示有多少个流多处理器(SM)正在使用。
    例如,一个持续运行单线程的kernel将获得 100% 的 GPU 利用率。

  • Est. SM Efficiency:预估SM效率。数值越高越好。此指标为kernel的 SM 效率,SM_Eff_K = min(该kernel的block数 / 该 GPU 的 SM 数,100%)。
    这个总数是所有kernel的 SM_Eff_K 乘以kernel执行持续时间后的总和,然后除以“所有步骤时间”。
    它显示了 GPU 流多处理器的利用率。
    虽然它比上面的“GPU 利用率”更精细,但它仍然不能完全展示全部情况。
    例如,每个块只有一个线程的kernel无法完全利用每个 SM。

  • Est. Achieved Occupancy:对于大多数情况,如内存带宽受限的kernel,更高的值通常意味着更好的性能,特别是当初始值非常低时。参考资料(http://developer.download.nvidia.com/GTC/PDF/GTC2012/PresentationPDF/S0514-GTC2012-GPU-Performance-Analysis.pdf)。占用率的定义在此处(https://docs.nvidia.com/gameworks/content/developertools/desktop/analysis/report/cudaexperiments/kernellevel/achievedoccupancy.htm)。
    Occupancy是一个 SM 上活跃 warps 的比率与该 SM 支持的最大活跃 warps 数的比率。kernel的理论Occupancy是该kernel的上限占用率,受多种因素限制,如kernel形状、kernel使用的资源和 GPU 的计算能力。
    kernel的预估实现Occupancy,OCC_K = min(kernel的线程数 / SM 数 / 每 SM 最大线程数,kernel的理论Occupancy)。
    这个总数是所有kernel的 OCC_K 使用kernel执行持续时间作为权重的加权和。它显示了细粒度的低级 GPU 利用率。

  • Kernel Time using Tensor Cores:用于Tensor Core kernel的总 GPU 时间 / 所有kernel的总 GPU 时间。数值越高越好。
    Tensor Core是 Volta GPU(如 Titan V)及以后 GPU 提供的混合精度浮点运算操作。
    cuDNN 和 cuBLAS 库包含了多数卷积和 GEMM 操作的几个启用了张量核心的 GPU kernel。
    这个数字显示了 GPU 上所有kernel中使用张量核心的时间比例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/549994.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SEO之搜索引擎的工作原理(三)

初创企业需要建站的朋友看这篇文章&#xff0c;谢谢支持&#xff1a;我给不会敲代码又想搭建网站的人建议 &#xff08;接上一篇。。。&#xff09; 排名 经过搜索引擎蜘蛛抓取页面&#xff0c;索引程序计算得到倒排索引后&#xff0c;搜索引擎就准备好可以随时处理用户搜索了…

基于Echarts的超市销售可视化分析系统(数据+程序+论文

本论文旨在研究Python技术和ECharts可视化技术在超市销售数据分析系统中的应用。本系统通过对超市销售数据进行分析和可视化展示&#xff0c;帮助决策层更好地了解销售情况和趋势&#xff0c;进而做出更有针对性的决策。本系统主要包括数据处理、数据可视化和系统测试三个模块。…

通义千问:官方开放API开发基础

目录 一、模型介绍 1.1主要模型 1.2 计费单价 二、前置条件 2.1 开通DashScope并创建API-KEY 2.2 设置API-KEY 三、基于DashScope SDK开发 3.1 Maven引入SDK 3.2 代码实现 3.3 运行代码 一、模型介绍 通义千问是由阿里云自主研发的大语言模型&#xff0c;用于理解和分…

JVM虚拟机(九)如何开启 GC 日志

目录 一、引言二、开启 GC 日志三、解析 GC 日志四、优化建议 一、引言 在 Java 应用程序的运行过程中&#xff0c;垃圾收集&#xff08;Garbage Collection&#xff0c;简称 GC&#xff09;是一个非常重要的环节。GC 负责自动管理内存&#xff0c;回收不再使用的对象所占用的…

贵阳市人民政府副市长刘岚调研珈和科技

4月9日&#xff0c;贵阳市人民政府副市长、党组成员刘岚一行到珈和科技走访调研&#xff0c;珈和科技总经理冷伟热情接待了考察团&#xff0c;就企业算力需求与合作&#xff0c;特色产业园区建设&#xff0c;科技成果转化落地等方面进行深入交流。 贵阳市教育局局长李波&#…

智能商品计划系统如何提升鞋服零售品牌的竞争力

国内鞋服零售企业经过多年的发展&#xff0c;已经形成了众多知名品牌&#xff0c;然而近年来一些企业频频受到库存问题的困扰&#xff0c;这一问题不仅影响了品牌商自身&#xff0c;也给长期合作的经销商带来了困扰。订货会制度在初期曾经有效地解决了盲目生产的问题&#xff0…

Vue加载glb / gltf模型(如何在vue中使用Three.js,vue使用threejs加载glb模型)

简介&#xff1a;Three.js 是一个用于在 Web 上创建和显示 3D 图形的 JavaScript 库。它提供了丰富的功能和灵活的 API&#xff0c;使开发者可以轻松地在网页中创建各种 3D 场景、模型和动画效果。可以用来展示产品模型、建立交互式场景、游戏开发、数据可视化、教育和培训等等…

RISC-V微架构验证

对于RISC-V处理器因其灵活性和可扩展性而受到广泛关注&#xff0c;但如果没有高效验证策略&#xff0c;错误的设计实现可能会影响RISC-V的继续推广。 在RISC-V出现之前&#xff0c;对于大多数半导体公司来说&#xff0c;处理器验证几乎成为一门屠龙之技。专业知识被浓缩到少数几…

基于afx透明视频的视觉增强前端方案

作者 | 青玉 导读 本文介绍了增长前端团队自研的Webview框架下透明视频视觉增强方案&#xff0c;该方案在保证对视觉进行高度还原的同时可投入更少的开发成本&#xff0c;还能获得更优的前端性能表现。文章首先分析了市面上动画方案的优缺点&#xff0c;然后详细介绍了透明视频…

stm32实现hid鼠标

启动CubelMX 选择芯片&#xff08;直接输入stm32f103zet6) 设置时钟 如下图 usb设置 配置usb设备 调试端口设置 配置时钟 项目输出设置 打开工程&#xff08;后记&#xff1a;此工程含有中文不能编译通过) 配置项目 配置调试器 编译无法通过 删除路径中的中文&#xff0c;以及…

如何将Oracle 中的部分不兼容对象迁移到 OceanBase

本文总结分析了 Oracle 迁移至 OceanBase 时&#xff0c;在出现三种不兼容对象的情况时的处理策略以及迁移前的预检方式&#xff0c;通过提前发现并处理这些问题&#xff0c;可以有效规避迁移过程中的报错风险。 作者&#xff1a;余振兴&#xff0c;爱可生 DBA 团队成员&#x…

盲人专用软件定制开发:突破出行壁垒,点亮生活之路

身为一名资深记者&#xff0c;我始终关注着各类社会群体面临的挑战与应对策略。今天&#xff0c;我将目光投向了一个特殊群体——盲人&#xff0c;以及一款旨在破解他们独立出行难题的盲人专用软件。这款应用叫做蝙蝠避障&#xff0c;它通过定制开发&#xff0c;以先进的技术手…

Achronix FPGA增加对Bluespec提供的基于Linux的RISC-V软处理器的支持,以实现可扩展数据处理

Bluespec支持加速器功能的RISC-V处理器将Achronix的FPGA转化为可编程SoC 2024年4月——高性能FPGA芯片和嵌入式FPGA&#xff08;eFPGA&#xff09;硅知识产权&#xff08;IP&#xff09;领域的领先企业Achronix半导体公司&#xff0c;以及RISC-V工具和IP领域的行业领导者Blues…

PySpark预计算ClickHouse Bitmap实践

1. 背景 ClickHouse全称是Click Stream&#xff0c;Data WareHouse&#xff0c;是一款高性能的OLAP数据库&#xff0c;既使用了ROLAP模型&#xff0c;又拥有着比肩MOLAP的性能。我们可以用ClickHouse用来做分析平台快速出数。其中的bitmap结构方便我们对人群进行交并。Bitmap位…

0基础如何入门编程?

0基础如何进入IT行业 &#xff1f; 前言 简介&#xff1a;对于没有任何相关背景知识的人来说&#xff0c;如何才能成功进入IT行业&#xff1f;是否有一些特定的方法或技巧可以帮助他们实现这一目标&#xff1f; 主要方法有如下几点建议提供给宝子们 目录 免费视频网课学习…

记录一下hive跑spark的insert,update语句报类找不到的问题

我hive能正常启动&#xff0c;建表没问题&#xff0c;我建了一个student表&#xff0c;没问题&#xff0c;但执行了下面一条insert语句后报如下错误&#xff1a; hive (default)> insert into table student values(1,abc); Query ID atguigu_20240417184003_f9d459d7-199…

【HCIP学习】OSPF协议基础

一、OSPF基础 1、技术背景&#xff08;RIP中存在的问题&#xff09; RIP中存在最大跳数为15的限制&#xff0c;不能适应大规模组网 周期性发送全部路由信息&#xff0c;占用大量的带宽资源 路由收敛速度慢 以跳数作为度量值 存在路由环路可能性 每隔30秒更新 2、OSPF协议…

十大排序——11.十大排序的比较汇总及Java中自带的排序算法

这篇文章对排序算法进行一个汇总比较&#xff01; 目录 0.十大排序汇总 0.1概述 0.2比较和非比较的区别 0.3基本术语 0.4排序算法的复杂度及稳定性 1.冒泡排序 算法简介 动图演示 代码演示 应用场景 算法分析 2.快速排序 算法简介 动图演示 代码演示 应用场景…

shell编程-1

shell编程 1 初识shell 1.1 文件描述符与输出重定向 FD (file descriptor) FD值英文含义0Standard Input正确输入&#xff0c;并返回在前端1Standard Output正确返回值2Standard Error Output错误返回值 常见格式 a.txt 1>a.txt 标准正确输出到a.txt 2>a.txt 准错…

5_vscode+valgrind+gdb调试程序

需求 项目程序, 读取串口数据, 出现程序崩溃问题valgrind 可以调试定位内存问题: 内存泄漏,非法地址访问,越界访问等内存问题vscode gdb 可视化调试效果, 比命令行简单快捷很多期望使用vscode valgrind gdb 调试程序内存异常, 崩溃退出的问题 环境准备 sudo apt install v…