<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Machine Learning | Yasen Jia</title><link>https://lupinjia.github.io/tags/machine-learning/</link><atom:link href="https://lupinjia.github.io/tags/machine-learning/index.xml" rel="self" type="application/rss+xml"/><description>Machine Learning</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Tue, 11 Aug 2026 00:00:00 +0000</lastBuildDate><image><url>https://lupinjia.github.io/media/icon_hu_5c64a4bee4457df8.png</url><title>Machine Learning</title><link>https://lupinjia.github.io/tags/machine-learning/</link></image><item><title>Learning-based Locomotion方法总结</title><link>https://lupinjia.github.io/blog/locomotion_review/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0000</pubDate><guid>https://lupinjia.github.io/blog/locomotion_review/</guid><description>&lt;p&gt;本文总结Locomotion的已有方法，包括blind locomotion和perceptive locomotion的方法。目前Locomotion的方法多与表征学习（Representation Learning）相结合，表征学习的目的是从数据中学习出有效、抽象的特征表示，帮助网络更高效地学习。&lt;/p&gt;
&lt;h2 id="blind_locomotion"&gt;blind_locomotion&lt;/h2&gt;
&lt;p&gt;blind_locomotion的方法可以分为两个大类：不使用表征学习和使用表征学习。&lt;/p&gt;
&lt;h3 id="不使用表征学习"&gt;不使用表征学习&lt;/h3&gt;
&lt;p&gt;不使用表征学习的blind locomotion的一般做法是堆叠本体感知的历史帧。本体感知的一帧 $o_t$ 一般包括$c_t, \omega_t, g_t, q_t, \dot{q}_t, a_{t-1}$ （$c_t$为命令，$\omega_t$为基座角速度，$g_t$为重力向量在基座坐标系中的投影，$q_t$为关节角度，$\dot{q}_t$为关节角速度，$a_{t-1}$为策略上一帧输出的动作）。这类方法的做法就是将本体感知的多帧$o_{t-H:t}$堆叠在一起输入给actor，然后再让actor输出动作$a_t$，。critic方面一般是输入全知的特权信息，包含本体感知信息以及只有仿真中才能获取的一些信息（基座线速度、连杆接触状态、足端高度、高度图等）。整体的架构如下所示：&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./vanilla_rl.png" alt="普通RL训练方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;给actor输入多帧本体感知能够增强策略的鲁棒性，核心的insight是&lt;strong&gt;本体感知的历史信息中包含了机器人状态随时间变化的规律，网络可以根据这些规律来应对更复杂的情况&lt;/strong&gt;（崎岖地形、受外力扰动等）。如果没有历史信息的话，网络只能根据当前时刻的感知来应对动态的环境，信息过于稀少。&lt;/p&gt;
&lt;h4 id="优势"&gt;优势&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;实现简单&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="缺点"&gt;缺点&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;训练效率低，学得慢&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="代表性文章"&gt;代表性文章&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="使用表征学习"&gt;使用表征学习&lt;/h3&gt;
&lt;p&gt;使用表征学习的方法可以分为多种形式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Teacher-Student系列：使用teacher encoder编码与任务相关的物理状态，sutdent encoder根据本体感知的历史信息预测teacher encoder的编码。具体又可以分为不同的实现形式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
：由ETH的Marco Hutter组提出的最原始的Teacher-Student实现，主要特点为两阶段训练，encoder和actor绑定在一起，二阶段蒸馏时用action loss来优化student的encoder和actor。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./original_ts.png" alt="原始Teacher-Student方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：CMU的Deepak Pathak组提出的Teacher-Student变体，仍然是两阶段训练，encoder和actor解绑，第一阶段训练完actor后第二阶段使用冻结的一阶段actor，二阶段蒸馏时用latent loss来优化student的encoder。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./rma.png" alt="RMA方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：MIT的Pulkit Agrawal组提出的Teacher-Student变体，单阶段训练，依然是encoder和actor解绑，训练时用latent loss来优化student的encoder，用RL的loss来优化teacher encoder和actor。这种方式中student没有实际和环境交互，类似于behavior cloning的idea，得到的student policy的效果并不好。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：SusTech的张巍组提出的并行Teahcer-Student方案，单阶段训练，最主要的创新是将env分为teacher和student两组，将RL loss中的surrogate loss形式化为teacher surrogate loss + student surrogate loss，从而在RL更新中同时考虑两者的return，实现互相反哺的效果。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./cts.png" alt="CTS方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：KAIST的Jemin Hwangbo组提出的估计器网络方法，单阶段训练，核心idea是在训练中添加一个估计器网络，从本体感知的历史信息中估计出来真实物理状态（基座线速度、足端接触状态、足端相对于地面的高度等），将这个估计的信息输入给actor，使其可以有更高效的信息输入。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./estimator_net.png" alt="EstimatorNet方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：KAIST的 Hyun Myung组提出的方法，通过预测下一步的observation来提取有效的中间表征，VAE的引入（与标准高斯分布的KL散度损失）使得隐变量聚集在一个超球面上，压缩了隐变量空间。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./dreamwaq.png" alt="DreamWaQ中的VAE的训练框图" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Contrastive Learning：相比于预测数值的回归的方式，对比学习提供了另一种方式来让策略隐式地理解环境状态与动力学。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
：上海AI Lab的庞江淼组提出的基于对比学习的盲走方案，单阶段训练，基于
方法得到隐向量的高效表征。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./himloco.png" alt="HimLoco方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：逐际动力的谌骅组提出的基于对比学习的盲走方案，单阶段训练，基于
方法得到隐向量的高效表征。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./pvp.png" alt="PvP方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="perceptive_locomotion"&gt;perceptive_locomotion&lt;/h2&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;这里的perceptive_locomotion只涉及深度图输入的运动控制策略&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于输入深度图的perceptive_locomotion来说，由于深度图的信息维度更高，冗余更多，所以不使用表征学习来提取低维有效表征所造成的训练效率低下会更显著。
这种任务的方法同样可以分为不使用表征学习和使用表征学习两大类。&lt;/p&gt;
&lt;h3 id="不使用表征学习-1"&gt;不使用表征学习&lt;/h3&gt;
&lt;p&gt;与blind_locomotion类似，这类方法就是简单粗暴的将信息输入给网络。只不过在深度图方面，会引入CNN来处理图像。
这类方法的代表是
，通过AMP+MoE的框架来学习拟人的perceptive_locomotion动作。&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./hiking_in_the_wild.png" alt="Hiking in the Wild架构图" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id="使用表征学习-1"&gt;使用表征学习&lt;/h3&gt;
&lt;p&gt;很多使用表征学习的perceptive_locomotion方法就是在blind_locomotion的框架基础上拓展而来的。大概可以分为以下几类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Teacher-Student系列：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
：CMU的Deepak Pathak组提出的方法，双阶段训练。论文中提出了两种训练方式，一种是直接沿袭RMA的方式，encoder和actor解耦，通过latent loss优化encoder；另一种是更贴合原始TS的方式，encoder和actor耦合，通过action loss优化encoder和actor。根据论文中展示的结果（Table 1），Monolithic的方式得到的student policy的性能更好。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./rma_depth.png" alt="RMA拓展方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：清华的赵行组提出的方法，使用两阶段的teacher-student训练，二阶段蒸馏时使用了BCE loss来优化，因为网络的输出被tanh限制在了[-1,1]之间，并且经过&lt;code&gt;(1+a)/2&lt;/code&gt;的变换最终到了[0,1]之间，覆盖概率的特征。本文的一个创新在于virtual obstacle的引入，实现快速的预训练。这一思想在后期的
中得到了继承，并利用
实现了更快速的穿透检测。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./virtual_obstacle.png" alt="Virtual Obstacles" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：CMU的Deepak Pathak组提出的方法，同样使用双阶段Teacehr-Student，利用action loss来优化encoder和actor。这篇文章中提出了用预定的落点来引导机器人的基座线速度命令，解决了velocity-based的policy在复杂地形上命令难以完美执行的问题。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./extreme_parkour.png" alt="Extreme Parkour方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：南科大的张巍组提出的方法，在原始的盲走CTS的框架基础上拓展深度图的输入，利用decoder来进一步约束latent的表征。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./cts_depth.png" alt="带深度图的CTS" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;EstimatorNet系列：这一系列的工作沿袭了EstimatorNet的&lt;strong&gt;估计物理状态&lt;/strong&gt;的思想，在perceptive_locomotion的任务中用容易获得的深度图估计高效的地形表征。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
：OSU的Alan Fern组提出的方法，主要idea是利用向前看的一个depth image来拟合机器人周身的heightmap，通过网络参数和仿真数据的scale，让单个视角的深度图也能拟合出来较为真实的heightmap。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./cassie_depth.png" alt="Cassie Perceptive Locomotion" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：ETH的Marco Hutter组提出的方法，用四足机器人前后左右四个深度相机拟合机器人周身360°的heightmap。策略在训练直接输入仿真中获取的heightmap，实物上直接输入拟合到的heightmap即可。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./nsr.png" alt="NSR方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：浙大的朱秋国组提出的方法，用向前看的深度相机拟合机器人前方的heightmap
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./start.png" alt="START的terrain reconstruction net训练框图" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
：逐际动力的谌骅组提出的方法，同样使用U-Net来拟合高度图
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./oli_depth.png" alt="高度图拟合方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DreamWaQ拓展：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
：浙大的朱秋国组提出的方法，沿袭了
的思路，利用VAE架构，通过拟合下一帧的obs以及当前的heightmap来获取中间表征
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./pie.png" alt="PIE方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;世界模型系列：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
：上交的张伟楠组提出的方法，利用
中提出的RSSM架构作为world model的架构，通过预测下一帧的深度图和本体感知来提取中间表征。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./wmp.png" alt="WMP方法" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>三种神经网络推理框架的推理速度对比</title><link>https://lupinjia.github.io/blog/inference_comparison/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0000</pubDate><guid>https://lupinjia.github.io/blog/inference_comparison/</guid><description>&lt;p&gt;本文对比三种神经网络推理架构（LibTorch，OpenVino，OnnxRuntime）的推理速度区别，涵盖了Python和C++两种语言的对比。&lt;/p&gt;
&lt;h2 id="推理架构介绍"&gt;推理架构介绍&lt;/h2&gt;
&lt;h3 id="libtorch"&gt;LibTorch&lt;/h3&gt;
&lt;p&gt;LibTorch是PyTorch官方提供的Torch C++接口库，提供了与PyTorch类似的接口来进行张量操作。考虑使用LibTorch是因为训练框架使用了PyTorch，导出的JIT Script可以直接使用LibTorch载入。安装LibTorch的流程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;确保有一个python3.10的环境&lt;/p&gt;
&lt;p&gt;在终端中输入&lt;code&gt;python&lt;/code&gt;可以进入python解释器，看到输出的提示信息中有版本信息。
如果现有的python不是3.10，可以安装一个miniconda，创建一个python3.10的环境。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安装好miniconda后&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;conda create -n env_name &lt;span class="nv"&gt;python&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.10
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下载
&lt;/p&gt;
&lt;p&gt;Pytorch官网也有提供whl文件下载，但那个whl文件只适用于x86架构的计算机。而Nvidia Jetson提供的whl文件需要有CUDA才能正常使用，所以我自己编译了一个whl文件，可以在RDKX5这种无CUDA的ARM计算机上使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装Pytorch&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;TORCH_INSTALL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;path/to/torch.whl
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python3 -m pip install --upgrade pip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python3 -m pip install numpy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python3 -m pip install --no-cache &lt;span class="nv"&gt;$TORCH_INSTALL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将CMakeLists.txt的&lt;code&gt;set(CMAKE_PREFIX_PATH path)&lt;/code&gt;中的path设为上述路径。&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;sudo find / -name &amp;quot;TorchConfig.cmake”&lt;/code&gt;即可找到LibTorch库的位置，最后使用的CMAKE_PREFIX_PATH类似于&lt;code&gt;xxx/python3.10/dist-packages/torch/share/cmake/Torch&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改CMakeLists，将LibTorch添加到链接库中，然后就可以使用LibTorch的C++接口了。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 根据自己的安装位置修改路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;CMAKE_PREFIX_PATH&lt;/span&gt; &lt;span class="s"&gt;/usr/local/lib/python3.10/dist-packages/torch/share/cmake/Torch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;find_package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;Torch&lt;/span&gt; &lt;span class="s"&gt;REQUIRED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;include_directories&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TORCH_INCLUDE_DIRS&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;target_link_libraries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;project_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TORCH_LIBRARIES&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于python来说，只需要&lt;code&gt;pip install torch&lt;/code&gt;即可安装torch。&lt;/p&gt;
&lt;h3 id="openvino"&gt;OpenVino&lt;/h3&gt;
&lt;p&gt;OpenVino是Intel推出的神经网络推理框架，支持多平台多架构部署，并且在每种平台每种架构下都进行了特定的优化来确保性能。目前对于Linux来说，Openvino支持的操作系统及设备如下：&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./openvino_supported_device.png" alt="OpenVino支持的设备及操作系统" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;OpenVino官方提供了很详细的文档，参考
，顺利安装了OpenVino之后，就可以修改CMakeLists使用OpenVino了：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;find_package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;OpenVINO&lt;/span&gt; &lt;span class="s"&gt;REQUIRED&lt;/span&gt; &lt;span class="s"&gt;COMPONENTS&lt;/span&gt; &lt;span class="s"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;ov_link_libraries&lt;/span&gt; &lt;span class="s"&gt;openvino::runtime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;target_link_libraries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;project_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ov_link_libraries&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;python：&lt;code&gt;pip install openvino&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="onnxruntime"&gt;OnnxRuntime&lt;/h3&gt;
&lt;p&gt;OnnxRuntime是一个专门使用onnx模型的多平台机器学习模型加速器，它具有灵活的接口，可以自由整合特定硬件的库。目前支持的平台如下：&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./ort_supported_device.png" alt="OnnxRuntime支持的平台" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;将
中的对应版本的压缩包下载下来，解压后有头文件（&lt;code&gt;include&lt;/code&gt;）和库文件（&lt;code&gt;lib&lt;/code&gt;），在CMakeLists中根据当前CPU架构选择对应的库文件使用即可：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# ---------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# onnxruntime (vendored C++ SDK in third_party/onnxruntime)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# lib/&amp;lt;arch&amp;gt;/ : arch-specific prebuilt libonnxruntime.so (x86_64 or arm64)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# include/ : arch-independent headers
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# ---------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;ONNXRUNTIME_DIR&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;${CMAKE_CURRENT_LIST_DIR}/third_party/onnxruntime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;ONNXRUNTIME_ARCH&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;${CMAKE_SYSTEM_PROCESSOR}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;NOT&lt;/span&gt; &lt;span class="s"&gt;ONNXRUNTIME_ARCH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;execute_process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;COMMAND&lt;/span&gt; &lt;span class="s"&gt;uname&lt;/span&gt; &lt;span class="s"&gt;-m&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;OUTPUT_VARIABLE&lt;/span&gt; &lt;span class="s"&gt;ONNXRUNTIME_ARCH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;OUTPUT_STRIP_TRAILING_WHITESPACE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;endif&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;ONNXRUNTIME_ARCH&lt;/span&gt; &lt;span class="s"&gt;MATCHES&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;^(AMD64|amd64|x86_64)$&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;ONNXRUNTIME_ARCH&lt;/span&gt; &lt;span class="s"&gt;x86_64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;elseif&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;ONNXRUNTIME_ARCH&lt;/span&gt; &lt;span class="s"&gt;MATCHES&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;^(aarch64|arm64)$&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;ONNXRUNTIME_ARCH&lt;/span&gt; &lt;span class="s"&gt;arm64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;else&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;FATAL_ERROR&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Unsupported onnxruntime architecture: ${ONNXRUNTIME_ARCH}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;endif&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;STATUS&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;onnxruntime architecture: ${ONNXRUNTIME_ARCH}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;ONNXRUNTIME_LIBRARY&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;${ONNXRUNTIME_DIR}/lib/${ONNXRUNTIME_ARCH}/libonnxruntime.so&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;NOT&lt;/span&gt; &lt;span class="s"&gt;EXISTS&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;${ONNXRUNTIME_LIBRARY}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;FATAL_ERROR&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;onnxruntime library not found: ${ONNXRUNTIME_LIBRARY}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;endif&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;find_package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;yaml-cpp&lt;/span&gt; &lt;span class="s"&gt;REQUIRED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;find_package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;spdlog&lt;/span&gt; &lt;span class="s"&gt;REQUIRED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Python: &lt;code&gt;pip install onnxruntime&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="测试条件"&gt;测试条件&lt;/h2&gt;
&lt;h3 id="神经网络模型参数"&gt;神经网络模型参数&lt;/h3&gt;
&lt;p&gt;模型整体是一个简单的MLP，参数量为283224（20W+）：
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./used_model_info.png" alt="使用的模型" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id="计算机参数"&gt;计算机参数&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Architecture: aarch64
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; CPU op-mode(s): 32-bit, 64-bit
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Byte Order: Little Endian
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CPU(s): 6
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; On-line CPU(s) list: 0-5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Vendor ID: ARM
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Model name: Cortex-A78AE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Model: 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Thread(s) per core: 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Core(s) per cluster: 3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Socket(s): -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Cluster(s): 2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Stepping: r0p1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; CPU max MHz: 1984.0000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; CPU min MHz: 115.2000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; BogoMIPS: 62.50
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 at
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; omics fphp asimdhp cpuid asimdrdm lrcpc dcpop
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; asimddp uscat ilrcpc flagm paca pacg
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Caches (sum of all):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; L1d: 384 KiB (6 instances)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; L1i: 384 KiB (6 instances)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; L2: 1.5 MiB (6 instances)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; L3: 4 MiB (2 instances)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="python"&gt;Python&lt;/h3&gt;
&lt;p&gt;使用
来测试不同推理框架的速度。在仿真中运行时是单循环运行，一个while loop中进行 更新obs -&amp;gt; 推理action -&amp;gt; 施加action（仿真步进decimation次）-&amp;gt; sleep到下一次策略推理：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;viewer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_running&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_running&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mujoco&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;physics_dt&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mujoco&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decimation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update_state&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dof_targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;policy_step&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ctrl_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dof_targets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在实机上运行时，low_state使用ROS2的节点实现，low_cmd的发布在每次策略推理时执行，策略推理在一个单独的进程（&lt;code&gt;inference_process&lt;/code&gt;）中进行。&lt;/p&gt;
&lt;h3 id="c"&gt;C++&lt;/h3&gt;
&lt;p&gt;使用
来测试不同推理框架的速度。该框架使用了一个自制的periodic_task类来实现周期性任务的执行，核心是一个基于绝对时间（absolute time）的时钟。&lt;/p&gt;
&lt;h2 id="python中三种推理框架速度对比"&gt;Python中三种推理框架速度对比&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;onnxruntime：平均推理时间为0.002966544s（约3ms），波动较大，经常跳到10ms以上
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./ort_py_spd.png" alt="onnxruntime, python推理速度" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;openvino：平均推理时间为0.004066487s（约4ms），波动较大，经常跳到10ms以上。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./openvino_py_spd.png" alt="openvino, python推理速度" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;libtorch：平均推理时间为0.002999146s（约3ms），波动较大，经常跳到10ms以上。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./libtorch_py_spd.png" alt="libtorch, python推理速度" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="c中三种推理框架速度对比"&gt;C++中三种推理框架速度对比&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;onnxruntime：平均推理时间为0.000242817s（约0.2ms），波动较小，偶尔跳到1ms以上。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./ort_cpp_spd.png" alt="onnxruntime, c&amp;#43;&amp;#43;推理速度" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;openvino：平均推理时间为0.000376115（约0.3ms），波动较小，偶尔跳到1ms以上。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./openvino_cpp_spd.png" alt="openvino, C&amp;#43;&amp;#43;推理速度" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;libtorch：平均推理时间为0.001684558（约1ms），第一次推理时会跳到100ms以上，其他时候波动较小，偶尔跳到1ms以上。
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="./libtorch_cpp_spd.png" alt="libtorch, C&amp;#43;&amp;#43;推理速度" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;推理框架&lt;/th&gt;
&lt;th&gt;Python推理速度（s，平均）&lt;/th&gt;
&lt;th&gt;C++推理速度（s，平均）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;onnxruntime&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.002966544&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.000242817&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;openvino&lt;/td&gt;
&lt;td&gt;0.004066487&lt;/td&gt;
&lt;td&gt;0.000376115&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;libtorch&lt;/td&gt;
&lt;td&gt;0.002999146&lt;/td&gt;
&lt;td&gt;0.001684558&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;总结来看，使用C++的onnxruntime最好，推理速度最快，波动最小。&lt;/p&gt;</description></item></channel></rss>