<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://moonout.link/feed.xml" rel="self" type="application/atom+xml" /><link href="https://moonout.link/" rel="alternate" type="text/html" /><updated>2026-07-20T21:35:23+08:00</updated><id>https://moonout.link/feed.xml</id><title type="html">Ni Mu</title><subtitle>Ni Mu&apos;s academic homepage --- Ph.D. student at Tsinghua University, working on reinforcement learning and large language models.</subtitle><author><name>Ni Mu</name><email>mn23@mails.tsinghua.edu.cn</email></author><entry><title type="html">（已解决）Linux · Ubuntu · VSCode︱VSCode 服务器下载失败，一直卡住、无法打开文件夹</title><link href="https://moonout.link/vscode-remote-server-download-fix/" rel="alternate" type="text/html" title="（已解决）Linux · Ubuntu · VSCode︱VSCode 服务器下载失败，一直卡住、无法打开文件夹" /><published>2026-04-16T00:00:00+08:00</published><updated>2026-04-16T00:00:00+08:00</updated><id>https://moonout.link/vscode-remote-server-download-fix</id><content type="html" xml:base="https://moonout.link/vscode-remote-server-download-fix/"><![CDATA[<p><br /></p>

<p>问题描述：</p>

<ul>
  <li>ssh 能连上 Ubuntu 20.04 的服务器，但是 VSCode 连接时，服务器一直显示在下载，一直下不好；</li>
  <li>解决 vscode 服务器下载失败问题后，希望打开 /~ 文件夹，这一步又打不开。</li>
</ul>

<p>解决步骤概览：</p>

<ul>
  <li>从本地下载 vscode 服务器，然后 scp 传到 ubuntu 机器上去。scp：参见本站博客，<a href="https://www.cnblogs.com/moonout/p/19552883">如何传输本地大文件至 Linux 服务器</a>。</li>
  <li>降级 Remote - SSH 插件版本。（还改了一下其他设置，但感觉以上两个改动最 work）</li>
  <li>此时，发现已经可以正常连 vscode 了，但还是打不开 /~ 文件夹。</li>
  <li>发现服务器 curl 不通 <code class="language-plaintext highlighter-rouge">www.google.com</code>，使用（本站博客）<a href="http://localhost:4000/local-machine-as-proxy-server/">Python · GitHub · Linux︱使用本/机作为代·理+服-务=器</a> 方法解决了网络问题。</li>
  <li>发现服务器没法 sudo apt update 和 sudo apt install 装包，使用 <a href="https://blog.csdn.net/weixin_42108533/article/details/154847719">换清华源</a> 的方法解决了这个问题。</li>
  <li>然后就可以打开 /~ 文件夹了，很神奇…</li>
</ul>

<hr />

<hr />

<h2 id="解决-vscode-服务器下载失败">解决 VSCode 服务器下载失败</h2>

<p>（kimi 提供的解决方案）</p>

<p>这是一个非常常见的问题，通常由<strong>网络问题</strong>或<strong>插件 Bug</strong> 导致。以下是几种最有效的解决方法：</p>

<hr />

<h3 id="方法-1强制从本地下载最简单">方法 1：强制从本地下载（最简单）</h3>

<p>（这个方法对我的场景不 work）</p>

<p>（感觉这个设置 不如不改，因为修改之后，原先连的很顺畅的服务器也连不上了，改回去就恢复正常了）</p>

<p>VS Code 默认会尝试让远程服务器下载，如果失败才会转为本地下载。你可以强制让它<strong>始终从本地下载</strong>，然后通过 scp 传到服务器：</p>

<ol>
  <li>打开 VS Code 设置（<code class="language-plaintext highlighter-rouge">Ctrl+,</code>）</li>
  <li>搜索 <code class="language-plaintext highlighter-rouge">Remote.SSH: Local Server Download</code></li>
  <li>将选项改为 <code class="language-plaintext highlighter-rouge">always</code></li>
</ol>

<p>这样可以绕过远程服务器下载慢或连不上外网的问题。</p>

<hr />

<h3 id="方法-2禁用-exec-server-模式解决插件-bug">方法 2：禁用 Exec Server 模式（解决插件 Bug）</h3>

<p>（这个方法对我的场景 疑似也不 work，我不确定，因为是跟后面的改动一起做的）</p>

<p>如果网络没问题但仍然卡住，可能是 Remote SSH 插件的 Bug。禁用 <code class="language-plaintext highlighter-rouge">Exec Server</code> 模式可以强制使用旧的连接方式：</p>

<ol>
  <li>打开 VS Code 设置</li>
  <li>搜索 <code class="language-plaintext highlighter-rouge">remote.SSH.useExecServer</code></li>
  <li><strong>取消勾选</strong>（设为 <code class="language-plaintext highlighter-rouge">false</code>）</li>
</ol>

<p>或者直接在 <code class="language-plaintext highlighter-rouge">settings.json</code> 中添加：</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"remote.SSH.useExecServer"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="err">,</span><span class="w">
</span><span class="nl">"remote.SSH.localServerDownload"</span><span class="p">:</span><span class="w"> </span><span class="s2">"always"</span><span class="w">
</span></code></pre></div></div>

<p>然后<strong>完全关闭 VS Code 重新打开</strong>。</p>

<hr />

<h3 id="方法-3手动下载-vs-code-server最可靠">方法 3：手动下载 VS Code Server（最可靠）</h3>

<p>（这个对我来说 work）</p>

<p>如果上述方法无效，可以手动下载服务器包：</p>

<p><strong>步骤 1：获取 Commit ID</strong></p>

<p>在 VS Code 中按 <code class="language-plaintext highlighter-rouge">Ctrl+Shift+P</code> → 输入 <code class="language-plaintext highlighter-rouge">About</code> → 找到<strong>提交</strong>（Commit）后面的字符串，例如：</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>38c31bc77e0dd6ae88a4e9cc93428cc27a56ba40
</code></pre></div></div>

<p><strong>步骤 2：手动下载服务器包</strong></p>

<p>用浏览器访问（将 <code class="language-plaintext highlighter-rouge">{commit_id}</code> 替换为你的 Commit ID）：</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://update.code.visualstudio.com/commit:{commit_id}/server-linux-x64/stable
</code></pre></div></div>

<p><strong>步骤 3：上传到服务器并解压</strong></p>

<p>通过 SSH 登录远程服务器，执行：</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 删除旧的（一定要删除）</span>
<span class="nb">rm</span> <span class="nt">-rf</span> ~/.vscode-server

<span class="c"># 创建目录（替换为你的 Commit ID）</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> ~/.vscode-server/bin/<span class="o">{</span>commit_id<span class="o">}</span>

<span class="c"># 将下载的 vscode-server-linux-x64.tar.gz 上传到上述目录</span>
<span class="c"># 然后解压</span>
<span class="nb">cd</span> ~/.vscode-server/bin/<span class="o">{</span>commit_id<span class="o">}</span>
<span class="nb">tar</span> <span class="nt">-zxvf</span> vscode-server-linux-x64.tar.gz <span class="nt">--strip-components</span> 1

<span class="c"># 清理</span>
<span class="nb">rm </span>vscode-server-linux-x64.tar.gz
</code></pre></div></div>

<p><strong>步骤 4：重新连接</strong>
关闭 VS Code 重新连接，此时会检测到已存在的服务器包，直接启动 。</p>

<hr />

<h3 id="方法-4回退-remote-ssh-插件版本">方法 4：回退 Remote SSH 插件版本</h3>

<p>（这个应该也有用，我是回退到了 0.107.1）</p>

<p>如果问题是升级后出现的，可以回退到稳定版本：</p>

<ol>
  <li>在扩展面板找到 <code class="language-plaintext highlighter-rouge">Remote - SSH</code></li>
  <li>点击”卸载”旁边的小箭头 → <strong>安装另一个版本</strong></li>
  <li>选择 <code class="language-plaintext highlighter-rouge">0.100.0</code> 或 <code class="language-plaintext highlighter-rouge">0.107.1</code> 等较稳定版本</li>
</ol>

<hr />

<h2 id="apt-install-安装换国内源">apt install 安装，换国内源</h2>

<p>请参考：<a href="https://blog.csdn.net/weixin_42108533/article/details/154847719">CSDN︱Ubuntu 20.04 LTS (Focal Fossa) 更换国内源的方法</a></p>

<p><strong>步骤 1：备份源列表</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo cp</span> /etc/apt/sources.list /etc/apt/sources.list.bak
</code></pre></div></div>

<p><strong>步骤 2：编辑源列表文件</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>vim /etc/apt/sources.list
</code></pre></div></div>

<p><strong>步骤 3：清空原内容并添加国内源</strong></p>

<p>我用的是清华源：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
</code></pre></div></div>

<p>现在，可以再试试 <code class="language-plaintext highlighter-rouge">sudo apt update</code>，应该就正常了。</p>

<p><br />
<br /></p>]]></content><author><name>Ni Mu</name><email>mn23@mails.tsinghua.edu.cn</email></author><category term="Linux" /><category term="Ubuntu" /><category term="VSCode" /><summary type="html"><![CDATA[解决 VSCode Remote-SSH 服务器一直下载失败，以及连上后无法打开 ~/ 文件夹的问题。]]></summary></entry><entry><title type="html">ARC-AGI：一个有趣的 LLM benchmark</title><link href="https://moonout.link/arc-agi-benchmark/" rel="alternate" type="text/html" title="ARC-AGI：一个有趣的 LLM benchmark" /><published>2026-01-07T00:00:00+08:00</published><updated>2026-01-07T00:00:00+08:00</updated><id>https://moonout.link/arc-agi-benchmark</id><content type="html" xml:base="https://moonout.link/arc-agi-benchmark/"><![CDATA[<p><br /></p>

<p>ARC-AGI benchmark 提供了基于视觉网格的谜题，这些谜题是“对于人类简单、对于大模型困难”的问题。ARC-AGI 通过评测大模型解决这类问题的能力，来衡量大模型距通用智能的距离。</p>

<p>每个谜题仅提供少量示例，大模型需要基于这些示例，通过抽象推理，理解谜题的含义。（另一方面，示例较少也意味着训练数据集较少，即，ARC-AGI benchmark 不容易通过专门训练来刷点。）该 benchmark 测试模型识别 pattern 并将其快速应用于新情况的能力。</p>

<p>ARC-AGI 的主要评估指标是 Pass@2，它衡量模型在两次尝试内生成正确输出的能力。</p>

<p>示例：</p>

<p align="center"><img src="https://arcprize.org/media/images/arc-task-grids.jpg" align="center" style="zoom:50%;" /></p>

<p align="center">(ARC-AGI-1)</p>
<p><br /></p>

<p align="center"><img src="https://arcprize.org/media/images/v2-example.png" align="center" style="zoom:50%;" /></p>

<p align="center">(ARC-AGI-2)</p>

<p>如何解决 ARC-AGI 问题？ARC-AGI 团队在 Kaggle 上发布了相关竞赛，然而，由于训练数据过少，无法训出一个用于解决 ARC-AGI 问题的模型（这个思想也与考察模型通用推理能力的初衷相悖），因此在 2024 年 GPT 等模型兴起之前，基于深度学习的方法并未取得好的结果。</p>

<p>根据 <a href="">ARC Prize 2024: Technical Report</a>，在 2024 年度，ARC-AGI 的求解取得突破，主要使用了以下三种方法：</p>

<ul>
  <li>深度学习引导的程序合成：利用深度学习模型，特别是专门的代码 LLMs，来生成解决任务的程序，或对搜索程序的过程进行指导。</li>
  <li>直推模型（transductive models）在测试时训练（test-time training，TTT）：在给定的 ARC-AGI 任务规范上对 LLM 进行微调，以便将 LLM 的先验知识重新组合成一个新的模型，适应当前的任务。直推模型指的是，接收输入后直接输出结果，而非输出一个程序。</li>
  <li>将程序合成与直推模型相结合：将上述两种方法合并为一个超级方法，因为据观察，这两种方法擅长解决不同类型的任务。</li>
</ul>

<hr />

<p>ARC-AGI 任务的官网：<a href="https://arcprize.org/">https://arcprize.org/</a></p>

<p>ARC-AGI-1/2/3 ：</p>

<ul>
  <li><a href="https://arcprize.org/arc-agi/1/">https://arcprize.org/arc-agi/1/</a></li>
  <li><a href="https://arcprize.org/arc-agi/2/">https://arcprize.org/arc-agi/2/</a></li>
  <li><a href="https://arcprize.org/arc-agi/3/">https://arcprize.org/arc-agi/3/</a></li>
</ul>

<p>ARC-AGI-1/2 的榜单：<a href="https://arcprize.org/leaderboard">https://arcprize.org/leaderboard</a></p>

<p>ARC Prize 2024: Technical Report：<a href="https://arxiv.org/html/2412.04604v1">https://arxiv.org/html/2412.04604v1</a></p>

<p>相关博客：</p>

<ul>
  <li>像 AI 写的神秘博客：<a href="https://labs.adaline.ai/p/what-is-the-arc-agi-benchmark-and">https://labs.adaline.ai/p/what-is-the-arc-agi-benchmark-and</a></li>
  <li><a href="https://zhuanlan.zhihu.com/p/30426666081">知乎 · 机器之心：「压缩即智能」得到实验验证，无需预训练和大量数据就能解决 ARC-AGI 问题</a></li>
  <li><a href="https://www.zhihu.com/question/7955529556/answer/65269819236">知乎：ARC-AGI 测试集对人工智能来说难在哪里？</a></li>
</ul>

<p><br />
<br /></p>]]></content><author><name>Ni Mu</name><email>mn23@mails.tsinghua.edu.cn</email></author><category term="LLM" /><category term="Benchmark" /><summary type="html"><![CDATA[ARC-AGI 设计了「对人简单、对模型困难」的视觉网格谜题，以评估大模型的通用智能能力。]]></summary></entry><entry><title type="html">PbRL︱近两年论文阅读的不完全总结</title><link href="https://moonout.link/pbrl-paper-reading/" rel="alternate" type="text/html" title="PbRL︱近两年论文阅读的不完全总结" /><published>2025-11-29T00:00:00+08:00</published><updated>2025-11-29T00:00:00+08:00</updated><id>https://moonout.link/pbrl-paper-reading</id><content type="html" xml:base="https://moonout.link/pbrl-paper-reading/"><![CDATA[<p><br /></p>

<p>（其实是博士生资格考试需要介绍的 20 篇文献… 选了比较熟悉的 20 篇，拼尽全力读完 10 篇，就读不动了… 读文献真是太难了……</p>

<hr />

<h2 id="-pbrl-deep-reinforcement-learning-from-human-preferences-christiano-2017">[🍵 PbRL] Deep reinforcement learning from human preferences (Christiano 2017)</h2>

<ul>
  <li>信息：PbRL 开山之作，NeurIPS 2017，提出了 PrefPPO。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/1706.03741">https://arxiv.org/abs/1706.03741</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/18558423">PbRL︱Christiano 2017 年的开山之作，以及 Preference PPO / PrefPPO </a></li>
</ul>

<p>这篇文章是 PbRL 的开山之作，（可能）首次明确提出了 PbRL 试图解决 address 的核心问题：对于那些目标复杂、定义模糊、难以用数学形式描述的 task，我们希望从 human feedback 中学习一个 reward model，并将其作为 RL 的奖励函数。</p>

<p>这个问题的现实意义在于：许多 real-world task 的目标非常复杂，难以用数学函数精确描述。手工设计奖励函数可能导致 reward hacking，需要反复进行 reward engineering，费时费力。如果有人类 demo / 专家数据，可以做 inverse RL 或 behavior cloning，但是很多任务难以给出人类 demo，比如控制奇形怪状的、跟人类很不像的机器人。而 PbRL 提出的 “比较而非打分”范式，可以显著降低人类认知负荷，让 agent 行为更自然地与人类意图对齐，做人类想做的事。</p>

<p>在 formulation 方面，文章定义 preference 可以由一个 underlying reward function 生成（第四页顶部）：通过比较两个 trajectory segment 的累计 reward 之和的大小关系来确定 preference。</p>

<p>然后，文章提出了用 Bradley-Terry model 来建模 preference 与 reward model 之间的关系，并设计了一个交叉熵 loss function，用于惩罚 “segment reward 之和的比较结果与 preference 不一致” 的情况，由此构建了 reward model 的学习方法。</p>

<p>在 method 方面，文章建立了 PbRL 基于 human feedback 学策略的流程：策略 $\pi$ 收集新数据 → 生成新 query → 获取 human feedback → 更新 reward model → 再训练 $\pi$ ，形成闭环。</p>

<p>论文声称 reward model 持续更新，值可能是非平稳的，因此选用对奖励函数变化较鲁棒的 online RL 的 policy gradient 方法：Atari 用 A2C，MuJoCo 用 TRPO。</p>

<p>发现，这篇文章已经提出了基于 disagreement 的 query selection：对于一个 query $(\sigma_0, \sigma_1)$，让 ensemble 这每个 reward model 给出 $\hat P[\sigma_0 \succ \sigma_1]$ 的值，计算这些值的方差，然后选一个方差最大的 query。</p>

<p>在 trick 方面，文章把 reward model 输出的值归一化到 0 1 之间，并且使用 reward model ensemble 归一化后的 reward 值取平均作为最终 reward。</p>

<p>在实验方面，文章做了 MuJoCo 的机器人和 Atari games，使用 oracle teacher / real human 来打 preference 标签，同时跟使用 ground-truth reward 的 RL 方法比较，将其作为 performance upper bound。实验非常充分。并且，实验证明，使用 prompt 好的 human 来打 preference，可以让 agent 学到新颖的行为，比如 hopper 后空翻。</p>

<p>在未来工作方面，因为是开山之作，这个工作比较初步，可以从以下两个方面改进：</p>

<ol>
  <li>样本效率：这个方法收敛太慢了，需要大量 preference label。我们需要要进一步提高 sample efficiency，去研究更高效的查询策略，或半监督 / 自监督预训练，比如 pebble、surf、QPA、stair 等工作。</li>
  <li>对 human preference 的鲁棒性：实验显示 real human 比 oracle scripted teacher 的样本效率低 40-50%，归因于标注不一致、错误、延迟（3.1 节的最后）。然而，这篇文章缺乏对 noisy label 的应对方式，只是简单丢弃“无法比较”的样本（2.2.2 节的最后一句话），缺乏对人类噪声的显式建模。后续的 B-Pref、RIME 等工作致力于应对 noisy label，而 sepoa、clarify 等工作聚焦于人类噪声的显式建模。</li>
</ol>

<h2 id="-pbrl-pebble-feedback-efficient-interactive-reinforcement-learning-via-relabeling-experience-and-unsupervised-pre-training">[🍵 PbRL] PEBBLE: Feedback-Efficient Interactive Reinforcement Learning via Relabeling Experience and Unsupervised Pre-training</h2>

<ul>
  <li>信息：PbRL 里程碑式工作，经典 PbRL baseline，ICML 2021。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2106.05091">https://arxiv.org/abs/2106.05091</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/17822778.html">PbRL︱PEBBLE：通过 human preference 学习 reward model</a></li>
</ul>

<p>上一篇 PrefPPO 提出了 PbRL 的基本框架，而 pebble 则是将这个框架发扬光大的工作。</p>

<p>个人理解，pebble 的核心贡献有三点：</p>

<ol>
  <li>off-policy RL 框架 + relabelling：首次将 SAC 这类 off-policy RL 算法引入 PbRL，并在每次 reward model 更新后，使用新模型对 replay buffer 中所有历史 transition 的 reward 进行 relabel。这显著提升了训练效率和 policy learning 速度，相较于 PrefPPO 的 on-policy 方法实现了数量级的加速。</li>
  <li>无监督探索预训练：在引入 reward model 和人类反馈之前，先基于纯探索驱动的预训练 生成有意义的行为片段，供人类进行偏好标注，从而极大提升了 query 的样本效率。具体而言，这个探索的 intrinsic reward 设计为 $r^\text{int}(s_t) = \log(|s_t - s_t^k|)$，将当前状态的 intrinsic reward 定义为与其 k-th nearest neighbor 之间的距离，从而鼓励访问状态熵更小、访问更稀疏的 state。（该思想参考了一篇 21 年的文章，将每个 transition 视作一个 particle 粒子）</li>
  <li>disagreement query selection：在 off-policy 框架上发扬光大了 PrefPPO 的 disagreement query selection 技术，通过 ensemble reward model 的方差来选择信息量最大的 segment pair 进行查询。</li>
</ol>

<p>介绍：PbRL 的提出动机 → PbRL 的 formulation → pebble 的具体 method → 实验结果。</p>

<p>pebble 提出 1 2 两个新技术的动机：</p>

<ul>
  <li>问题一：冷启动困境。传统 PbRL 初始查询质量低，agent 行为随机，人类难判断优劣，导致前期学习进展缓慢。</li>
  <li>问题二：样本效率 vs 反馈效率的矛盾。on-policy 方法虽能规避奖励非平稳性，但样本效率极低。pebble 证明：off-policy 学习 + relabelling 可以在不增加反馈量的前提下，将样本效率提升 5-10 倍，这对真实机器人学习至关重要，能减少磨损、降低训练时间成本。</li>
</ul>

<p>pebble 的具体算法如算法 2 所示，第五页顶部。</p>

<p>在实验方面，pebble 的实验主要做了 3 个 MuJoCo task 和 6 个 metaworld task，这些 task 的 action space 都是连续的，因为 SAC 只能做连续 action（不同于 PrefPPO 的 Atari 离散任务）。具体实验结果见图 3-5。</p>

<p>在未来工作方面，pebble 作为 PbRL 的里程碑式工作，对后续 PbRL 工作有深远的影响：</p>

<ol>
  <li>范式固化：pebble 几乎把 PbRL 的默认范式确立为 off-policy + relabelling，后续几乎没有 on-policy PbRL 工作了。</li>
  <li>Benchmark 标准化：后续 PbRL 基本都会做 MuJoCo 和 metaworld 任务，pebble 成为了一个必须超越的强 baseline。</li>
  <li>未来研究方向指引：pebble 的实验结果说明 1. query selection、2. 预训练 是很值得做的。这两个方向均有后续研究，如 QPA、sepoa、clarify、stair 关注 query selection，而 sepoa 关注预训练。</li>
  <li>遗留问题：pebble 跟 PrefPPO 一样，仍然未处理 noisy label 的问题。</li>
</ol>

<h2 id="-pbrl-surf-semi-supervised-reward-learning-with-data-augmentation-for-feedback-efficient-preference-based-reinforcement-learning">[🍵 PbRL] SURF: Semi-supervised reward learning with data augmentation for feedback-efficient preference-based reinforcement learning</h2>

<ul>
  <li>信息：PbRL 最早的几篇文章之一，ICLR 2022，6 6 6。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2203.10050">https://arxiv.org/abs/2203.10050</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/17826284.html">PbRL︱SURF：使用半监督学习，对 labeled segment pair 进行数据增强</a></li>
</ul>

<p>surf 在 pebble 的基础上，聚焦于提升 PbRL 中 feedback efficiency，主要使用了两个半监督学习的技术，对 preference label 进行数据增强：</p>

<ul>
  <li>半监督奖励学习（4.1 节）：利用 agent 与环境交互产生的海量未标注数据（存储在 buffer 中的历史经验），通过 pseudo-labeling 技术提炼监督信号。仅采纳置信度 &gt;0.99 的预测，避免噪声标签污染。</li>
  <li>时序数据增强（4.2 节）：对标注过的 query 做”时间裁剪”。核心假设是：对行为片段做轻微的时间平移 / 裁剪后，人类的偏好判断不变。比如”开门”任务中，只截取伸手到门把手那 3 秒，和展示完整 5 秒开门过程，人类大概率仍偏好成功开门的那段。</li>
</ul>

<p>在实验结果方面，surf 做了 3 个 MuJoCo 任务和 6 个 metaworld 任务。在同等 feedback 数量下，surf 的性能显著优于 pebble。</p>

<p>在未来工作方面，surf 成为了一个提升 PbRL 性能的 即插即用的模块。同时，surf 说明对 preference label 做数据增强，是有意义的研究方向，后续工作 LiRE 沿着这一思路继续推进。</p>

<h2 id="-pbrl-reward-uncertainty-for-exploration-in-preference-based-reinforcement-learning-rune">[🍵 PbRL] Reward uncertainty for exploration in preference-based reinforcement learning (RUNE)</h2>

<ul>
  <li>信息：PbRL 最早的几篇文章之一，ICLR 2022 的文章，5 6 6 6。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2205.12401">https://arxiv.org/abs/2205.12401</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/17824689.html">PbRL︱RUNE：鼓励 agent 探索 reward model 更不确定的 (s,a)</a></li>
</ul>

<p>rune 在 pebble 的基础上，为 policy learning 额外引入了一个 SAC reward 之外的 intrinsic reward，以此加速策略学习过程。</p>

<p>（这个故事可以讲的很好听）这篇论文的核心洞察是：人类对某些 state-action pair 的反馈不够多，导致 reward model $\hat r(s,a)$ 在这些区域的不确定性很高。这种不确定性，本身就是有价值的信号 —— 它告诉 agent 应该去这些 “人类还没说清楚” 的区域探索，从而主动收集更有信息量的反馈。</p>

<p>在 method 方面，具体的，$r^\text{total} = \hat r_\text{mean}(s,a) + \text{std}[\hat{ \boldsymbol{r}}(s,a)]$  ，即在 ensemble reward model 的均值基础上，额外加上 reward model 的标准差作为 intrinsic reward。</p>

<p>在实验方面，rune 做了 metaworld 的任务，主要实验结果见图 3 和表 1。</p>

<p>在未来工作方面，rune 跟 pebble 一样，仍未处理 noisy label 问题。然而，noisy label 对 rune 来说是，尤其致命：如果 reward model 在某些 (s,a) 上 uncertainty 很大，并非因为 reward model 对这些行为了解不足，而是人类本身难以判断这些行为的好坏（例如处于人类偏好边界、无法明确区分好坏），那么，即使 agent 充分探索这些行为，其 reward model 的方差也不会降低；同时，agent 也不应该去学习这些模棱两可的行为。后续工作 clarify 在一定程度上直接解决了这个问题，通过 query selection 机制，主动筛选出人类能够清晰判断的 query 供人类标注。</p>

<h2 id="-pbrl-b-pref-benchmarking-preference-based-reinforcement-learning">[🍵 PbRL] B-Pref: Benchmarking Preference-Based Reinforcement Learning</h2>

<ul>
  <li>信息：PbRL 最早的 noisy label benchmark，2021 NeurIPS Datasets and Benchmarks Track，7 7 8。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2111.03026">https://arxiv.org/abs/2111.03026</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/17868387.html">PbRL︱B-Pref：生成多样非理性 preference，建立 PbRL benchmark</a></li>
</ul>

<p>B-Pref 是 PbRL 领域最早的 noisy label benchmark。个人认为，B-Pref 的核心贡献在于 提出了以下 noisy scripted teacher 机制：
\(P[σ^i\succ σ^j~;~β,γ]=\frac{\exp\big(β\sum_{t=1}^Hγ^{H-t}r(s^i_t,a^i_t)\big)}
    {\exp\big(β\sum_{t=1}^Hγ^{H-t}r(s^i_t,a^i_t)\big) + \exp\big(β\sum_{t=1}^Hγ^{H-t}r(s^j_t,a^j_t)\big)}\)
具体的，这是一个基于 ground truth reward function $r$ 给出 scripted teacher 的 preference label 的概率模型，形式为每个 segment 的（discounted）reward 之和的 softmax。B-Pref 支持以下 noisy teacher 或非理想 teacher：</p>

<ul>
  <li>Oracle（先知）：β → ∞，指不再以 softmax 形式按概率打 preference，而是直接根据 segment reward 之和的大小，输出一个确定性的 preference。</li>
  <li>Myopic behavior（短视）：计算 segment reward 之和时，让 discounted factor 变小。</li>
  <li>Skipping queries（感觉不可比，跳过）：若两个 segment 的 reward 之和都太小，则认为两个 segment 都没有做到预期行为，一样差，跳过。</li>
  <li>Equally preferable（同样好，(0.5,0.5) ）：若两段 segment 的 reward 之和的差＜一个阈值，则认为性能太接近，比不出来，返回 (0.5,0.5)。</li>
  <li>Making a mistake（犯错，01 翻转）：以概率 ε 将 preference 标签翻转。</li>
</ul>

<p>（解释，为什么要用 scripted teacher：我们承认 PbRL 的终极目标是服务真实人类，但算法研发阶段必须有一个 1. 可以大规模开展实验、2. 可量化比较结果并复现 的评估体系，所以现有工作大多使用 scripted teacher 完成主实验，再补充一些相对小规模、能负担得起的人类实验。</p>

<p>在未来工作方面，B-Pref 关注的是 PbRL 里的 noisy label 问题，这是一个很有意义的研究方向，启发了后续的 RIME、sepoa、clarify 等工作。同时，B-Pref 对 noise 的建模还比较初步。进一步结合人类的认知特质来做更贴近真实的 noise 建模，并设计出在这些 noise 下更鲁棒的算法，是一个很有意义、能直接推动 PbRL 落地的方向，这正是 sepoa 和 clarify 试图 address 的问题。</p>

<h2 id="-pbrl-benchmarks-and-algorithms-for-offline-preference-based-reward-learning-oprl">[🍵 PbRL] Benchmarks and Algorithms for Offline Preference-Based Reward Learning (OPRL)</h2>

<ul>
  <li>信息：offline PbRL 的 pebble，TMLR 2023 年 3 月发表。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2301.01392">https://arxiv.org/abs/2301.01392</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/17829801.html">PbRL · offline RL：OPRL：发现部分 D4RL tasks 不适合做 offline reward learning</a></li>
</ul>

<p>这篇文章关注 offline PbRL，我们先来解释这个 setting。</p>

<ul>
  <li>首先，在 offline 方面，我们无法访问可交互的 env，只能使用离线数据集。offline 这个 setting 是重要的，因为有些时候 env 难以交互，比如 env 是真实世界 运转太慢 直接操作具有危险性，而我们有大量的历史运行数据，这个 setting 就非常适合建模为 offline RL。</li>
  <li>其次，在 PbRL 方面，这个 offline dataset 是没有 reward 标注的，我们必须利用已有的 human preference 数据集，或者从 offline dataset 里选一些数据 query human，训一个 PbRL 的 reward model，然后给这些 offline 数据标上 reward。</li>
</ul>

<p>这篇文章的主要贡献有 4 个：</p>

<ol>
  <li>正式提出了 offline PbRL 这个 setting；</li>
  <li>提出了 OPRL 算法，这是一个 naive 的 offline PbRL 的算法；</li>
  <li>【重要】在 reward learning 的视角下，评测了 D4RL benchmark 的各个任务，发现对于很多 task，只要给出质量足够高的 offline dataset，使用全 0 或随机 reward，性能也能学得很好；这证明，这些任务不适合用来评测 reward learning 的性能好坏。这部分内容对应 5.1 节。</li>
  <li>实验验证了提出的 OPRL 方法。</li>
</ol>

<p>在 method 方面，OPRL 的算法流程见算法 1（第 7 页顶端），首先进行 query selection 和 reward learning 的迭代，然后使用训好的 reward model 标记 offline dataset 的 reward，做经典 offline RL。query selection，OPRL 使用了 pebble 的 disagreement。</p>

<p>在 5.1 节里，这篇文章定义了一个 degradation 指标，用来衡量一个数据集是否适合评价 reward learning 方法。计算方式是 max(GT - max(AVG, ZERO, RANDOM), 0) / (GT - min(AVG, ZERO, RANDOM)，其中 GT  AVG ZERO RANDOM 代表使用 ground truth reward function、所有 reward 都赋成 transition 的平均 reward、全 0 reward 和随机 reward。直观上，AVG ZERO RANDOM 代表纯使用 offline 轨迹信息、不使用有效的 reward 信息，policy 能学出来的最好性能，而这个 degradation 要求使用 ground truth reward 学到的 policy 性能，要跟 AVG ZERO RANDOM 拉开差距。表 1 标记出了 degradation 超过 20% 的 task，用来后续评测。</p>

<p>在未来工作方面，</p>

<ul>
  <li>（其实感觉 offline PbRL 比 online PbRL 的 setting 更复杂，因为这个 setting 下 policy 的性能，不仅由 reward 学的是否好决定，还由 offline dataset 的质量决定；但 offline PbRL 的 setting，本身是重要的。）</li>
  <li>OPRL 仍未关注 noisy label 的问题，这个问题即使在 offline 场景下，也是值得关注的。</li>
  <li>此外，offline PbRL 中，有一些直接把 reward model 干掉，直接使用 preference 优化 policy 的工作，比如 IPL、DPPO、OPPO 等，（可能是我的幻觉）感觉 online PbRL 很少有这种工作。</li>
</ul>

<h2 id="-pbrl-rime-robust-preference-based-reinforcement-learning-with-noisy-preferences">[🍵 PbRL] RIME: Robust Preference-based Reinforcement Learning with Noisy Preferences</h2>

<ul>
  <li>信息：应对 noisy label 的 PbRL 工作，ICML 2024 Spotlight，3 6 8。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2402.17257">https://arxiv.org/abs/2402.17257</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/18323447">PbRL︱RIME：用交叉熵 loss 大小分辨 preference 是否正确 + 内在奖励预训练 reward model</a></li>
</ul>

<p>rime 关注 PbRL 中的 noisy label 问题。主要贡献有两个：</p>

<ol>
  <li>denoising discriminator：指的是，我们使用一个判别器，判断一下某个样本的 preference 是否打错了（打反了）。核心 method 是对训练 reward model 的 Bradley-Terry model 的交叉熵 loss 取一个阈值 $\ln \rho + \alpha \rho$，其中 $\rho$ 是自适应调整的超参数，α 是可调的超参数。直观来说，我们训神经网络时，忘了一般会先学到 general 的规律，再过拟合噪点数据（此时噪点数据的 loss 值更大）；如果 reward model 已经训的很好了，那么错 label 的交叉熵 loss 值应该更大一些。这个方法是有理论支持的（定理 4.1），下面详细说。</li>
  <li>reward model 的 warm start：（使用 pebble 流程）在从基于探索的预训练 转到基于 preference 的 policy learning 这个过程中，rime 观察到因为 reward model 在学习初期是 undeveloped 的，所以会把我们已经预训练的有一定行为的 policy 学坏，导致这个转变过程的性能下降。rime 提出，可以用探索过程的 intrinsic reward 训一下 reward model，具体的，直接使用 L2 loss 让 reward model 的输出值接近归一化后的 intrinsic reward（公式 9 10）。</li>
</ol>

<p>在理论方面，我们来详细解释一下定理 4.1。</p>

<ul>
  <li>假设我们已经有一个（用干净数据）训好的 reward model，其中交叉熵 loss 以 ρ 为界，即 $\mathcal L^\text{CE}(x)\le\rho$ ；</li>
  <li>这个式子也可以解读为 $H(P,Q) = H(P) + D_\text{KL}(P|Q) \le \rho$，其中 P 是 ground truth 的 0 1 preference 标签，而 Q 是 reward model 的 preference 概率预测（然后发现 P 是确定性的，熵 H(P) = 0）；</li>
  <li>则有，样本 x 的预测偏好 $P_\psi(x)$ ，和错 preference $\tilde y(x)=1-y$ 之间的 KL 散度，下限为 $D_{\mathrm{KL}}(\tilde{y}(x)\parallel P_{\psi}(x))\geq-\ln\rho+\frac{\rho}{2}+O(\rho^{2})$ ，定理 4.1 就在证明这个。</li>
</ul>

<p>在 method 方面，12 页的算法 1 提供了算法伪代码。ρ 是动态、自适应更新的，被赋值为 上一轮可信样本的最大交叉熵 loss。这个可信样本的集合也是动态维护的，第一轮，初始化 ρ ← ∞，认为所有 label 全都可信，后面开始训交叉熵 loss，才得到一个有效的 ρ 值。</p>

<p>在实验方面，rime 主要使用了 B-Pref 的 mistake teacher，即，会随机翻转一些 label。图 1 2 和表 1 2 都是 mistake teacher 的实验结果，而表 3 是 B-Pref 提出的各种非理想 teacher 的实验结果的平均值。</p>

<p>在未来工作方面，rime 研究了 noisy label，但 noisy 的机制仍然太过简单，假设 preference label 随机翻转。进一步结合人类的认知特质来做更贴近真实的 noise 建模，并设计出在这些 noise 下更鲁棒的算法，是一个很有意义、能直接推动 PbRL 落地的方向，这正是 sepoa 和 clarify 试图 address 的问题。</p>

<h2 id="-pbrl--offline-listwise-reward-estimation-for-offline-preference-based-reinforcement-learning-lire">[🍵 PbRL] [🍯 offline] Listwise Reward Estimation for Offline Preference-based Reinforcement Learning (LiRE)</h2>

<ul>
  <li>信息：ICML 2024。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2408.04190">https://arxiv.org/abs/2408.04190</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/18578551">offline RL · PbRL︱LiRE：构造 A&gt;B&gt;C 的 RLT 列表，得到更多 preference 数据</a></li>
</ul>

<p>lire 使用构建 RLT（Ranked List of Trajectories）即 segment 的有序列表的形式，对 preference label 进行数据增强。</p>

<p>在 method 方面，lire 的思想是，基于插入排序去维护一个 RLT。目标是得到形式为 $L=[g_1\prec g_2\prec ⋯\prec g_s]$ 的 RLT，其中 $g_i={σ_{i_{1}},\cdots,σ_{i_{k}}}$ 是一组具有相同人类偏好程度的 segment，是 preference label = 0.5 导致的。具体流程是，我们每拿到一个新 segment，就通过插入排序的方式与当前 RLT 中的元素进行比较，找到这个 segment 应插入的位置；直到构建这个 RLT 的 feedback 预算用完。</p>

<p>在 trick 方面，lire 能 work 依赖于魔改 Bradley-Terry model，将概率从指数形式的 φ(x) = exp(x) 改成线性的 φ(x) = x。lire 声称，这样做能更好建模二阶偏好关系，因为指数函数在 segment reward 之和很大的适合，可能会有梯度消失（？），而线性函数能放大高奖励区域的差异，对区分”好”与”极好”至关重要（？）。图 2 empirically 证明了，这种 linear 形式的魔改可以学到更真的 reward model，子图 d 里的点分布更象一条 y=x 下的直线；然而，子图 c 的 reward 学的很差，这似乎意味着，将这种线性魔改应用于 使用 500 / 1000 个反馈的 MR 方法并不 work。</p>

<p>在实验方面，表 2 是主实验结果。</p>

<p>在未来工作方面，</p>

<ul>
  <li>lire 做这种基于 ranked list 的数据增强，依赖于对 preference 传递性的假设，即如果 A &gt; B, B &gt; C，应该也有 A &gt; C。然而，这种假设在现实生活中不一定成立，比如石头剪刀布，就直接违反了这个假设。目前还没有看到 address 这个问题的工作，可能是有的，但我已经有一段时间没读 PbRL 新文章了。</li>
  <li>lire 关注 offline PbRL，但感觉这个 method 也能应对 online PbRL。</li>
</ul>

<h2 id="-pbrl-query-policy-misalignment-in-preference-based-reinforcement-learning-qpa">[🍵 PbRL] Query-Policy Misalignment in Preference-Based Reinforcement Learning (QPA)</h2>

<ul>
  <li>信息：ICLR 2024 Spotlight，8 6 6。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2305.17400">https://arxiv.org/abs/2305.17400</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/17909138.html">PbRL︱QPA：选择 near on-policy query，加速 policy learning 收敛速度</a></li>
</ul>

<p>QPA 关注通过 query selection 加速 policy learning、提升 PbRL 性能。</p>

<p>感觉 QPA 的故事讲的非常好：</p>

<ul>
  <li>query selection 方面的 gap：先前方法 如 pebble、OPRL 等 普遍认为，在 query selection 方面，query selection 应当选择 “信息量最大（informative）” 的 query，从而让 reward model 获得尽可能多的信息。然而，存在一个反直觉现象：这些 query selection 策略往往只比随机选 query 略好一点，反馈效率提升有限。</li>
  <li>被忽视的 query-policy misalignment 现象：QPA 发现，选择的看似 informative 的 query，实际上可能跟当前 RL agent 的兴趣不一致，因此对 policy learning 几乎没有帮助，最终导致 feedback-efficiency 低下。这就像在教学生做数学题时，却讲解语文知识，信息再”丰富”也无助于当前学习。</li>
  <li>query-policy misalignment 现象 的直观验证（第 4 节）：图 2 可视化了使用 random、disagreement 和 near on-policy query selection 方法选出来的 query。可以看出，random 和 disagreement 都会选到当前不关心的 query（绿圈圈出），并且看 curve 发现，这两种方法学习效率都不高，不如 near on-policy query selection。这个例子非常直观，curve 也符合 QPA 所声称的实验现象。</li>
  <li>query-policy aligned 的 PbRL 方法：1. Near On-policy Query Selection，仅在 replay buffer 最近收集到的轨迹里采 query，2. Hybrid Experience Replay，SAC 更新 policy 的 transition 一半在 near on-policy buffer 里采，另一半在整个 replay buffer 里采。</li>
</ul>

<p>在实验方面，QPA 的主实验是图 5 6，显示出 QPA outperform 了一系列强 baseline。（QPA 是加了 surf 的）</p>

<p>在未来工作方面，QPA 揭示了一个直觉：在某些情况下，”局部精准”优于”全局粗糙”，或者说”局部精准”与”全局精准”大致等价，但是”局部精准”性价比更高。后续工作 stair 也沿这一思路推进。</p>

<h2 id="-pbrl--offline-preference-transformer-modeling-human-preferences-using-transformers-for-rl">[🍵 PbRL] [🍯 offline] Preference Transformer: Modeling Human Preferences using Transformers for RL</h2>

<ul>
  <li>信息：ICLR 2023，5 6 6 8。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2303.00957">https://arxiv.org/abs/2303.00957</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/18056289">offline RL · PbRL︱Preference Transformer：反正感觉 transformer 很强大</a></li>
</ul>

<p>PT 使用 transformer 来建模 reward model，公式可以写成：
\(\begin{aligned}
P[σ^i\succ σ^j] = &amp; 
\frac{\exp\big( \text{Transformer}[r(s^i_t,a^i_t)] \big)}
    {\exp\big( \text{Transformer}[r(s^i_t,a^i_t)] \big) + 
    \exp\big( \text{Transformer}[r(s^j_t,a^j_t)] )\big)}
\\
    = &amp; \frac{\exp\big( \sum_{i=0}^{H-1} w_t^i \cdot \hat{r}(s^i_t,a^i_t) \big)}
    {\exp\big( \sum_{i=0}^{H-1} w_t^i \cdot \hat{r}(s^i_t,a^i_t) \big) + 
    \exp\big( \sum_{i=0}^{H-1} w_t^j \cdot \hat{r}(s^i_j,a^j_t) )\big)}
\end{aligned}\)
其中 w 可以被理解为，我们给一个 segment 里每个 (s,a) 的关注程度 / 权重；这正好与 transformer 的 qkv 形式对应上：在 value × softmax(key^T query)，weight 正好对上 softmax(key^T query)，而 reward model 对应上 value。</p>

<p>在 motivation 方面，传统强化学习假设奖励函数是马尔可夫、时序独立的，给每个动作即时打分。然而，人类评判行为时不是这样：我们看一段机器人操作视频，注意力会自然被关键转折时刻吸引（比如”差点掉落但成功挽回”比”平稳执行”更印象深刻），且当前判断会受历史上下文影响（同样的动作，发生在”已经失衡”和”稳定状态”下意义完全不同）。</p>

<p>这正是 Preference Transformer 的核心洞见：人类偏好是非马尔可夫的、时序加权的。论文提出用 Transformer 建模这种偏好结构，通过：1. 因果 Transformer 捕捉历史依赖（非马尔可夫奖励），2. 双向注意力层自动学习 重要性权重 softmax(key^T query)，3. 加权求和 建模最终偏好判断。</p>

<p>审稿人也认为这个 motivation 是有道理的，说如果奖励实际上是 non-Markovian 的，那么 Transformer 的想法是有动机的（well motivated）。</p>

<p>在实验方面，表 1 和图 3 是主要实验结果，证明 PT 形式的 reward model 比其他 markov / non-markov 形式的 reward model 性能更好，并且权重能学到一个 segment 里人类关心的帧。</p>

<p>在未来工作方面，将 human preference 建模为非马尔可夫模型，感觉是有意义和有价值的，这个故事是好的。</p>

<h2 id="-offline-decision-transformer-reinforcement-learning-via-sequence-modeling">[🍯 offline] Decision Transformer: Reinforcement Learning via Sequence Modeling</h2>

<ul>
  <li>信息：NeurIPS 2021，6 6 7 9 poster。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2106.01345">https://arxiv.org/abs/2106.01345</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/18037872">offline RL：读读 Decision Transformer </a></li>
</ul>

<p>DT 提出了一种基于 hindsight 思想和 transformer 序列建模思路的新 RL 方法，应用于 offline RL 场景。</p>

<p>故事主线：传统 RL 依赖于动态规划，而 Decision Transformer 提出”序列建模”新范式：用监督学习解决 RL 任务，把控制问题变成”条件文本生成”，用 transformer 预测轨迹的下一 token（action）。</p>

<p>在动机方面，</p>

<ol>
  <li>DT 没有 bellman 的更新，而是使用监督学习拟合离线数据，因此避免了 Q 高估、bootstrapping 不稳定等的问题；</li>
  <li>DT 使用 hindsight return 作为条件，适用于稀疏 reward，而传统 RL 对于稀疏 reward 因为监督信号太少 所以性能不好；这是有道理 并且很重要的，最早的 hindsight 工作 HER 提出的动机也是解决稀疏 reward 问题。</li>
  <li>DT 使用 transformer，输入包含轨迹的所有历史状态，因此适合非马尔可夫决策，而传统 RL 做不了非马尔可夫决策；</li>
  <li>DT 声称自己因为不学 value function，因此即使在 offline RL 的 setting 下，也不需要一些策略约束或者对 value function 的悲观约束。</li>
</ol>

<p>在 method 方面，核心 method 见图 1（第一页），核心算法见算法 1（第五页），大概是先给 transformer 塞进去 (s, a, R, s, a, …, s) 的序列（加 positional embedding），然后希望它输出下一 token 的预测内容，即 action。loss function 就是 a 和 a hat 的 L2 loss（连续 action）/ 交叉熵 loss（离散 action）。</p>

<p>R 代表 return 或 reward-to-go，指的是从当前步到整个 episode 结束，还有多少 reward，把这些 reward 求和。这是一种 hindsight 的思想：我们提供关于这个轨迹的其余 / 未来部分，然后训练一个策略，使得它可以满足这些未来要求。</p>

<p>在实验方面，DT 做了 Atari 和 D4RL 的 MuJoCo 任务，主实验见表 1-4，改变 hindsight（reward-to-go）看性能 curve 的实验见图 4。DT 的性能超过或至少持平，CQL 等强 offline RL baseline。</p>

<p>在未来工作方面，</p>

<ol>
  <li>decision transformer 这种机制，可能只适用于 offline，并不适用于 online RL。（印象里有一篇 online DT 文章，但那个应该做的是 online 微调 DT，而不是纯 online 训练一个 DT。）这大概是因为，Transformer 需要大量数据才能有效训练 并展现出优势，而传统 RL 用函数近似，样本效率更高。</li>
  <li>DT 需要手动设定 hindsight，才能部署策略。在实验中，DT 的 hindsight 被设置为 1× 或 5× 最大回报。因此在某些程度上，部署 DT 策略仍然需要一些先验知识，（不像为最大化 discounted reward 而训的 RL 策略，可以直接部署使用）。不过，一个 conditioned policy 也算是需要先验知识的，因为需要设置 condition z，DT 作为一个 conditioned policy，这一点也可以理解。</li>
  <li>DT 隐含 return 的单调性假设，reward 最好每一步都 ≥ 0。不然，策略看到一个 reward-to-go，会无法判断 是应该继续获取 reward，还是应该先吃一点 penalty 再吃更大量的 reward。因此，在给 DT 用的 offline 数据集标 reward 时，应该做相关 reward shaping，比如直接线性 scale 到 reward 全 ≥ 0。</li>
  <li>对于无限 horizon，或 offline dataset 里轨迹长度参差不齐的情况，DT 该如何 work？或许，对于数据集里的轨迹，我们可以将其切分 / 填充，保证每个分段的长度为 K，制造一个统一的 horizon。将 DT 部署至无限 horizon 时，我们可以使用长度为 K 的滑动窗口来设计 reward-to-go。另一方面，或许也可以尝试 discounted reward-to-go，但 DT 特地没有加 discount，不知道这样做是否会影响性能。</li>
  <li>个人感觉，基于 hindsight 这种思想，把 RL 任务变成监督学习，还是激动人心的。下一篇文章 HIM 就是这个思想的延申。</li>
</ol>

<h2 id="-offline-generalized-decision-transformer-for-offline-hindsight-information-matching-him">[🍯 offline] Generalized Decision Transformer for Offline Hindsight Information Matching (HIM)</h2>

<ul>
  <li>信息：将 decision transformer 扩展成了 HIM，ICLR 2022，6 8 8 spotlight。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2111.10364">https://arxiv.org/abs/2111.10364</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/18038364">offline RL：HIM：基于 hindsight 的 RL 是一类大 idea</a></li>
</ul>

<p>这篇文章是 DT 的扩展。这也应该是我第一次读到这种，将 A 范式扩展成更 generalized 的 A0，并提出属于 A0 范式的 B C 方法的文章。</p>

<p>HIN 的 hindsight 故事：</p>

<table>
  <tbody>
    <tr>
      <td>强化学习一个根本痛点是样本效率极低，每个轨迹只能为单一目标提供监督信号。比如，一个机器人踢球轨迹，如果目标是”射进球门”，那么”踢到门柱”这个轨迹就被浪费了。这催生了 hindsight 思想：用未来信息为轨迹重新标注”伪目标”，解决监督信号太稀疏的问题。已有很多基于 hindsight 思想的工作：HER 用未来状态做目标，DT 用 reward-to-go 做条件。HIM 总结：这些方法本质上都在做同一件事 —— 训练一个条件策略 $π(a</td>
      <td>s,z)$，使得策略生成的轨迹的”信息统计量”，与给定的目标 $z$ 匹配。这个统计量可以是：</td>
    </tr>
  </tbody>
</table>

<ul>
  <li>HER 的未来状态 $φ_T$</li>
  <li>DT 的未来轨迹 reward 求和（reward-to-go）</li>
  <li>模仿学习的完整轨迹 $\tau$</li>
  <li>甚至可以是一个分布（如 reward 的直方图）</li>
</ul>

<p>这就是 HIM（hindsight information matching）框架：最小化生成轨迹的统计量 $I^Φ(τ)$ 与目标 z 之间的散度$D(I^Φ(τ), z)$。</p>

<p>具体的，HIM 提出通用架构GDT：基于 Decision Transformer，通过改变两个部件，即可适配任意 HIM 问题：</p>

<ul>
  <li>特征函数 Φ(s,a)：决定提取什么信息（奖励 DT 及其分布 CDT、状态维度 HER 及其分布 BDT、自编码特征 BDT）</li>
  <li>反因果聚合器：决定如何汇总未来信息（求和→DT，分箱→CDT，第二Transformer→BDT）</li>
</ul>

<p>然后，HIM 提出了两个算法实例化：</p>

<ul>
  <li>CDT (Categorical DT)：将特征空间离散化，用直方图作为目标，实现首个有效的 offline 多任务 SMM 算法，可以同时学会多种行为 如跑和前空翻，只要给出对应的状态框架分布。</li>
  <li>BDT (Bi-directional DT)：将 $I_\Phi$ 设置为反因果 Transformer，聚合完整状态序列的特征，从而实现高效的 one-shot 模仿学习。</li>
</ul>

<p>在 method 方面，核心算法见算法 1，在最后一页（28 页）。</p>

<p>在实验方面，HIM 使用 D4RL medium-expert 数据集，按累积奖励对所有轨迹进行排序，将五个最佳轨迹和五个 50% 的轨迹作为测试集（总共 10 个轨迹），并将其余轨迹用作训练集。</p>

<p>在未来工作方面，</p>

<ul>
  <li>CDT 的 hindsight 信息是状态分布，所以如果（需要考虑的）state space 过大，比如使用 pixel 状态，可能会导致学的不够好。</li>
  <li>HIM 仍然是 offline 工作；HIM 策略的质量被 offline 数据集的质量所限制，不过这是 offline RL 的固有问题。</li>
  <li>我知道有些 offline RL 算法，能学到比数据集里最好行为 还要好的行为，比如在 medium-replay 数据集上训练，得到性能超过 medium 的 policy，不知道 DT HIM 框架能否做到。不过 HIM 的 6.2.1 节发现，合成目标可诱导新行为，所以说不定是有潜力的。</li>
  <li>但是 hindsight 思想还是很好的，感觉这个工作做的非常好。下一篇文章 OPPO 就是使用这种 hindsight 框架做 PbRL 的工作。</li>
</ul>

<h2 id="-pbrl--offline-beyond-reward-offline-preference-guided-policy-optimization-oppo">[🍵 PbRL] [🍯 offline] Beyond Reward: Offline Preference-guided Policy Optimization (OPPO)</h2>

<ul>
  <li>信息：ICML 2023。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2305.16217">https://arxiv.org/abs/2305.16217</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/18038454">offline RL · PbRL︱OPPO：PbRL 场景的 offline hindsight transformer</a></li>
</ul>

<p>在 A+B 场景中应用了 C 方法：A - PbRL、B - offline RL、C - HIM。</p>

<p>先简单介绍 ABC 的 setting，凑时长。</p>

<p>然后介绍 OPPO 的故事，训一个 reward model 是信息瓶颈。</p>

<p>然后声称 OPPO 直接使用了 BDT 类似思想的 HIM 方法，维护了两个 transformer，一个作为 encoder，输入 trajectory 输出 z，另一个作为策略，输入 z 作为 hindsight，输出预测的 action。</p>

<p>然后，说 OPPO 在轨迹的 embedding space 里，设计对比学习 loss，形式为一个三元的 anchor 正样本 负样本 的对比学习，既把 正样本 负样本至少拉开一个 margin，又确保我们的 anchor 离正样本比离负样本总要近一个 margin。</p>

<p>这个方法启发了后续工作 clarify。</p>

<h2 id="-offline-a-minimalist-approach-to-offline-reinforcement-learning-td3bc">[🍯 offline] A Minimalist Approach to Offline Reinforcement Learning (TD3+BC)</h2>

<ul>
  <li>信息：NeurIPS 2021，8 7 7 5。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2106.06860">https://arxiv.org/abs/2106.06860</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/17842272.html">offline RL：TD3+BC：在最大化 Q advantage 时添加 BC loss 的极简算法</a></li>
</ul>

<p>直接对着博客讲故事。</p>

<h2 id="-multi-objective-a-generalized-algorithm-for-multi-objective-reinforcement-learning-and-policy-adaptation-eql">[🥑 multi-objective] A Generalized Algorithm for Multi-Objective Reinforcement Learning and Policy Adaptation (EQL)</h2>

<ul>
  <li>信息：可能是第一篇有收敛性保证的 MORL 工作，NeurIPS 2019。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/1908.08342">https://arxiv.org/abs/1908.08342</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/19258625">MORL：Envelope Q-Learning：有收敛性保证的 MORL 算法</a></li>
</ul>

<p>首先介绍 MORL 的 setting，然后介绍单目标的 value iteration 为何收敛，然后介绍 EQL 理论，最后介绍 trick。</p>

<p>未来工作：可以考虑结合 PbRL，变成 Pb-MORL。</p>

<h2 id="-exploration-exploration-by-random-network-distillation-rnd">[🍇 exploration] Exploration by Random Network Distillation (RND）</h2>

<ul>
  <li>信息：ICLR 2019，10 9 7 4。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/1810.12894">https://arxiv.org/abs/1810.12894</a></li>
  <li>open review：<a href="https://openreview.net/forum?id=H1lJJnR5Ym">https://openreview.net/forum?id=H1lJJnR5Ym</a></li>
  <li>博客：
    <ul>
      <li>站内最相关的博客：<a href="https://www.cnblogs.com/moonout/p/17294248.html">RL 的探索策略：Exploration for RL</a> ，参见 2.3 节。</li>
      <li>站外博客：<a href="https://zhuanlan.zhihu.com/p/485476646">知乎：强化学习探索家：令人拍案叫绝的RND (1)</a> ， <a href="https://zhuanlan.zhihu.com/p/146309991">知乎：RND: EXPLORATION BY RANDOM NETWORK DISTILLATION</a></li>
    </ul>
  </li>
</ul>

<p>RND 的核心思想是，intrinsic reward = $|\hat f(s;\hat \theta) - f(s; \theta)|_2^2$，并且每次采到 state，都最小化这个均方误差。</p>

<p>RND 有 trick：为 task reward 和基于随机网络的 intrinsic reward 训练两个 value 网络。</p>

<p>（以下为 kimi 的回答）</p>

<p>论文在第 2.3 节专门讨论了这个问题，核心原因有以下几点：</p>

<p>1 内在奖励与外在奖励的本质差异：</p>

<ul>
  <li>（这一条没看懂）情景性不同：内在奖励采用 non-episodic 设置，即不因为”游戏结束”而截断折扣累积，而外在奖励保持 episodic 设置。这是因为，内在奖励衡量的是未来所有新颖状态的总和，不应因一次失败而重置；而外在奖励若采用非情景设置，智能体会通过故意”送死”来重复获取早期奖励。</li>
  <li>时间尺度不同：论文实验显示，内在奖励的最佳折扣因子 γ_I = 0.99，而外在奖励需要更大的折扣因子 γ_E = 0.999 才能取得好效果（图5）。不同的折扣因子需要独立的价值估计。</li>
  <li>平稳性不同：外在奖励函数是平稳的（stationary），而内在奖励随着预测器学习不断衰减，是非平稳的（non-stationary）。分离的价值网络可以为内在奖励提供更稳定的监督信号。</li>
</ul>

<p>2 数学分解的可行性： 由于回报在奖励上是线性的，总回报可分解为 R = R_E + R_I。因此可以分别训练两个价值头 V_E 和 V_I，再合并为 V = V_E + V_I。这种分解使得不同特性的奖励流可以灵活组合，而不必强行用一个网络拟合混合的回报。</p>

<p>在未来工作方面，RND 可能无法应对 noisy-TV 问题，如果 state 中有大量随机的分量，RND 可能会失效。但感觉 RND 应该适用于连续 state space。</p>

<h2 id="-exploration-episodic-novelty-through-temporal-distance-etd">[🍇 exploration] Episodic Novelty Through Temporal Distance (ETD)</h2>

<ul>
  <li>信息：ICLR 2025，8 8 6 5 poster。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2501.15418">https://arxiv.org/abs/2501.15418</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/18812958">RL · Exploration：ETD：使用时序距离构造 intrinsic reward，鼓励 agent 探索 </a></li>
</ul>

<p>直接对着博客讲故事。</p>

<h2 id="-skill-discovery-dos-and-donts-learning-desirable-skills-with-instruction-videos">[🍄 skill discovery] Do’s and Don’ts: Learning Desirable Skills with Instruction Videos</h2>

<ul>
  <li>信息：NeurIPS 2024。</li>
  <li>arxiv：<a href="https://arxiv.org/abs/2406.00324">https://arxiv.org/abs/2406.00324</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/18983738">Skill Discovery︱DoDont：使用 do + don’t 示例视频，引导 agent 学习人类期望的 skill</a></li>
</ul>

<p>先讲 skill discovery 的无监督基本思想，互信息，可区分之类。</p>

<p>然后简单讲 metra。</p>

<p>然后说 skill discovery 的问题，引入 GSD。</p>

<p>然后讲 dodont 的故事。</p>

<p>然后说 dodont 基于 metra 的 DSD 框架，魔改距离度量，并通过换元把它放到了 intrinsic reward 里。</p>

<h2 id="基于事件的优化方法简介及其在能源互联网中的应用">基于事件的优化方法简介及其在能源互联网中的应用</h2>

<ul>
  <li>信息：控制理论与应用，2018 年。</li>
  <li>pdf 链接：<a href="https://www.labxing.com/files/lab_publications/69-1520929024-5gRwvDWe.pdf">www.labxing.com</a></li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/16315306.html">概述：基于事件的优化方法 / 事件驱动优化 / Event-Based Optimization / EBO</a></li>
</ul>

<h2 id="面向数据中心绿色可靠运行的强化学习方法">面向数据中心绿色可靠运行的强化学习方法</h2>

<ul>
  <li>信息：智能科学与技术学报，2020 年。</li>
  <li>pdf 链接：没找到合适的，或许可以去知网搜索。</li>
  <li>百度文库：<a href="https://wenku.baidu.com/view/ffc3261fff4ffe4733687e21af45b307e871f9f8?_wkts_=1763743882252">链接</a> 。</li>
  <li>博客：<a href="https://www.cnblogs.com/moonout/p/19254926">数据中心 + 事件驱动优化：面向数据中心绿色可靠运行的强化学习方法</a></li>
</ul>

<p><br />
<br /></p>]]></content><author><name>Ni Mu</name><email>mn23@mails.tsinghua.edu.cn</email></author><category term="PbRL" /><category term="Reinforcement Learning" /><summary type="html"><![CDATA[对近两年 preference-based reinforcement learning 等方向论文的不完全阅读整理。]]></summary></entry><entry><title type="html">【总集篇】Linux ｜ 如何创建一个 home 目录在 /data 磁盘的 sudo 用户</title><link href="https://moonout.link/sudo-user-home-on-data-disk/" rel="alternate" type="text/html" title="【总集篇】Linux ｜ 如何创建一个 home 目录在 /data 磁盘的 sudo 用户" /><published>2025-04-02T00:00:00+08:00</published><updated>2025-04-02T00:00:00+08:00</updated><id>https://moonout.link/sudo-user-home-on-data-disk</id><content type="html" xml:base="https://moonout.link/sudo-user-home-on-data-disk/"><![CDATA[<p><br /></p>

<p>需求：</p>

<p>拿到了 boss 的服务器账号 ssh boss@172.16.1.100，需要登录 boss 的账号，然后为自己创建一个账号，实现 ssh <user_name>@172.16.1.100 登录。
我希望自己的账号 1. 有 sudo 权限，2. home 目录的空间大。</user_name></p>

<p>（boss、<user_name> 和 172.16.1.100 地址均为虚设。）</user_name></p>

<hr />

<h2 id="01-创建新用户">01 创建新用户</h2>

<p>先查看一下服务器上有哪些用户：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> /etc/passwd
<span class="c"># 每行格式为：</span>
<span class="c"># 用户名:密码占位符:UID:GID:注释:家目录:默认shell</span>
<span class="nb">cut</span> <span class="nt">-d</span>: <span class="nt">-f1</span> /etc/passwd  <span class="c"># 只查看用户名</span>
</code></pre></div></div>

<p>更多命令：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">who</span>          <span class="c"># 查看当前登录的用户</span>
w            <span class="c"># 查看当前登录用户及其活动</span>
<span class="nb">users</span>        <span class="c"># 简单列出当前登录的用户名</span>
last         <span class="c"># 查看最近登录记录</span>
</code></pre></div></div>

<h3 id="1-确认大容量磁盘的位置">1 确认大容量磁盘的位置</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">df</span> <span class="nt">-h</span>      <span class="c"># 查看文件系统的磁盘空间，确认大容量分区挂载点</span>
</code></pre></div></div>

<p>具体来说：</p>

<ul>
  <li>df 是 “disk free” 的缩写，用于报告文件系统的磁盘空间使用情况。</li>
  <li>-h 选项表示以人类可读的格式（如 KB, MB, GB）显示磁盘空间，而不是以字节为单位。</li>
</ul>

<p>运行 df -h 命令后，会看到类似以下的输出：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Filesystem      Size  Used Avail Use% Mounted on
udev            7.8G     0  7.8G   0% /dev
tmpfs           1.6G  2.4M  1.6G   1% /run
/dev/sda1        233G   50G  173G  23% /
tmpfs           7.8G  124M  7.7G   2% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           7.8G     0  7.8G   0% /sys/fs/cgroup
/dev/sdb1        917G  200G  667G  22% /mnt/data
tmpfs           1.6G     0  1.6G   0% /run/user/1000
</code></pre></div></div>

<p>每一列的含义如下：</p>

<ul>
  <li>Filesystem: 文件系统名称。</li>
  <li>Size: 总大小。</li>
  <li>Used: 已使用的空间。</li>
  <li>Avail: 可用空间。</li>
  <li>Use%: 磁盘空间使用率。</li>
  <li>Mounted on: 挂载点。</li>
</ul>

<h3 id="2-创建新用户并指定-home-目录">2 创建新用户并指定 Home 目录</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 假设我们希望把 home 目录建到 /data 下面</span>
<span class="nb">sudo </span>useradd <span class="nt">-m</span> <span class="nt">-d</span> /data/&lt;user_name&gt; <span class="nt">-s</span> /bin/bash &lt;user_name&gt;
</code></pre></div></div>

<p>其中，</p>
<ul>
  <li>-m：自动创建Home目录（若父目录/data存在）</li>
  <li>-d：指定自定义Home目录路径</li>
  <li>-s：设置默认shell为bash</li>
</ul>

<h3 id="3-设置用户密码">3 设置用户密码</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>passwd &lt;user_name&gt;
<span class="c"># 根据提示输入两次新密码</span>
</code></pre></div></div>

<h3 id="4-授予新用户-sudo-权限">4 授予新用户 sudo 权限</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>usermod <span class="nt">-aG</span> <span class="nb">sudo</span> &lt;user_name&gt;
</code></pre></div></div>

<p>验证目录权限：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo chown</span> <span class="nt">-R</span> &lt;user_name&gt;:&lt;user_name&gt; /data/&lt;user_name&gt;  <span class="c"># 确保目录归属正确</span>
<span class="nb">ls</span> <span class="nt">-ld</span> /data/&lt;user_name&gt;                       <span class="c"># 检查权限应为 drwxr-xr-x</span>
</code></pre></div></div>

<h3 id="5-测试登录">5 测试登录</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh &lt;user_name&gt;@172.16.1.100
<span class="c"># 输入密码后验证：</span>
<span class="nb">pwd</span>      <span class="c"># 应显示 /data/&lt;user_name&gt;</span>
<span class="nb">df</span> <span class="nt">-h</span> <span class="nb">.</span>  <span class="c"># 查看当前目录所在分区的空间</span>
</code></pre></div></div>

<p>如遇登录失败，检查 /etc/ssh/sshd_config，确保允许密码认证（PasswordAuthentication yes），或直接在 boss 用户里设置 <user_name> 用户的 ssh 密钥。</user_name></p>

<h2 id="02-配置环境的后续工作">02 配置环境的后续工作</h2>

<ul>
  <li>
    <table>
      <tbody>
        <tr>
          <td>设置 ssh 密钥登录，可以免密码登录服务器：[Linux · ssh</td>
          <td>如何使用 ssh 密钥，免密码登录 Linux 服务器](https://www.cnblogs.com/moonout/p/18334148)</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>如果连不上 vscode：[Linux · Ubuntu · VSCode</td>
          <td>（已解决）VSCode 服务器下载失败，下载一直卡住，无法打开文件夹](https://www.cnblogs.com/moonout/p/19885819)</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>安装 conda：[Conda</td>
          <td>如何在 Linux 服务器安装 conda](https://www.cnblogs.com/moonout/p/18334292) ，[Conda</td>
          <td>如何在 Linux 服务器安装 miniconda](https://www.cnblogs.com/moonout/p/18802012)</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>配置 git 和 GitHub 访问权限：[Git</td>
          <td>如何在新服务器上配置 git](https://www.cnblogs.com/moonout/p/18334937)</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>配置代理：[Python · GitHub · Linux</td>
          <td>使用本机作为代理服务器](https://moonout.link/local-machine-as-proxy-server/)</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>安装 MuJoCo、mujoco_py：[Python · MuJoCo</td>
          <td>MuJoCo 与 mujoco_py 的版本对应，以及安装 Cython&lt;3](https://www.cnblogs.com/moonout/p/18666968)</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>新建 conda 环境：conda create –name <env_name> python=3.8</env_name></li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>安装 dm_control 等库：[Python · Jax</td>
          <td>在 python 3.8 上安装 jax，运行 offline RL 的 IQL](https://www.cnblogs.com/moonout/p/18667147)</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>为大目录（如下载的模型）创建软链接：<a href="https://www.cnblogs.com/moonout/p/18646449">用 ln 命令创建软链接，Linux 系统</a></li>
</ul>

<p><br />
<br /></p>]]></content><author><name>Ni Mu</name><email>mn23@mails.tsinghua.edu.cn</email></author><category term="Linux" /><category term="运维" /><summary type="html"><![CDATA[拿到服务器账号后，为自己创建一个有 sudo 权限、home 目录在大容量磁盘上的用户，并梳理配置开发环境的后续步骤。]]></summary></entry><entry><title type="html">Python · GitHub · Linux︱使用本机作为代理服务器</title><link href="https://moonout.link/local-machine-as-proxy-server/" rel="alternate" type="text/html" title="Python · GitHub · Linux︱使用本机作为代理服务器" /><published>2025-01-23T00:00:00+08:00</published><updated>2025-01-23T00:00:00+08:00</updated><id>https://moonout.link/local-machine-as-proxy-server</id><content type="html" xml:base="https://moonout.link/local-machine-as-proxy-server/"><![CDATA[<p><br /></p>

<p><em>致谢同学教我这种方法。</em></p>

<hr />

<h3 id="01-配置-http-代-理">01 配置 HTTP 代-理</h3>

<p>假设本机的 c·l-a+s=h 的端口是 7890，则在 vscode 的 ssh config 里，修改：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">Host server_alias</span>
    <span class="s">HostName 123.45.67.162</span>
    <span class="s">User &lt;user_name&gt;</span>
    <span class="s">RemoteForward 127.0.0.1:7890 127.0.0.1:7890</span>  <span class="c1"># 添加这一行</span>
</code></pre></div></div>

<p>这个文件应该在本机的 /user/.ssh 目录下。</p>

<p>然后，在服务器的 ~/.bashrc 里添加：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">http_proxy</span><span class="o">=</span><span class="s2">"http://127.0.0.1:7890"</span>
<span class="nb">export </span><span class="nv">https_proxy</span><span class="o">=</span><span class="s2">"http://127.0.0.1:7890"</span>
<span class="nb">ulimit</span> <span class="nt">-n</span> 65535
</code></pre></div></div>

<p>并 source ~/.bashrc 。</p>

<p>临时把·代+理=关掉：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">http_proxy</span><span class="o">=</span><span class="s2">""</span>
<span class="nb">export </span><span class="nv">https_proxy</span><span class="o">=</span><span class="s2">""</span>
</code></pre></div></div>

<h3 id="02-配置-ssh-代理">02 配置 ssh 代/理</h3>

<p>参考博客：<a href="https://seepine.com/git/ssh-proxy/">https://seepine.com/git/ssh-proxy/</a></p>

<p>修改服务器 ~/.ssh 目录下的 config 文件，如果没有则新建这个文件：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">Host github.com</span>
    <span class="s">Hostname ssh.github.com</span>
    <span class="s">Port </span><span class="m">443</span>
    <span class="s">User git</span>
    <span class="s">ProxyCommand nc -v -x 127.0.0.1:7890 %h %p</span>  <span class="c1"># 添加这一行</span>
</code></pre></div></div>

<p>如果没有 nc 命令，则需要</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt update
<span class="nb">sudo </span>apt <span class="nb">install </span>netcat
</code></pre></div></div>

<p>通过 ssh -T git@github.com 来测试是否配置成功。</p>

<p>如果 ssh 连 github 时，出现这个报错：Bad owner or permissions on /home/yyq_mn/.ssh/config，则需要修改 .ssh 目录下各个文件的权限：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 1. 确保 .ssh 目录和 config 文件的所有者是你自己（不要用 root）</span>
<span class="nb">sudo chown</span> <span class="nt">-R</span> &lt;user_name&gt;:&lt;user_name&gt; ~/.ssh

<span class="c"># 2. 设置正确的权限</span>
<span class="nb">chmod </span>700 ~/.ssh
<span class="nb">chmod </span>600 ~/.ssh/config
<span class="nb">chmod </span>600 ~/.ssh/id_rsa        <span class="c"># 如果有私钥</span>
<span class="nb">chmod </span>644 ~/.ssh/id_rsa.pub    <span class="c"># 公钥可以宽松一点</span>
</code></pre></div></div>

<h3 id="03-用服务器-a-做访问服务器-b-的-跳-板-机">03 用服务器 A 做访问服务器 B 的~ 跳~ 板~ 机~</h3>

<p>在 vscode 的 ssh config 里，修改：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">Host server_A</span>
    <span class="s">HostName 123.45.67.162</span>
    <span class="s">User &lt;user_name&gt;</span>

<span class="s">Host server_B</span>
    <span class="s">HostName 123.45.67.165</span>
    <span class="s">User &lt;user_name&gt;</span>
    <span class="s">ProxyCommand ssh -W %h:%p server_A</span>  <span class="c1"># 添加这一行</span>
</code></pre></div></div>

<h3 id="04-一些修网记录">04 一些修网记录</h3>

<p>（参考：<a href="https://blog.csdn.net/a2267542848/article/details/119893382">CSDN︱ssh 方向代理 Warning: remote port forwarding failed for listen port 问题</a>）</p>

<p>如果与服务器的连接突然断开了，想重新连服务器的时候，发现配置的-本·机+代=理^不 work，可以在服务器上尝试以下命令：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>netstat <span class="nt">-plant</span> | <span class="nb">grep </span>7890  <span class="c"># 查询服务器上占住 7890 端口的程序</span>
<span class="c"># 大概率是原来残留的那个连接，需要把它杀掉。示例输出：</span>
<span class="c"># tcp 0 0 127.0.0.1:38302 127.0.0.1:7890 CLOSE_WAIT  1748765/nc</span>
<span class="nb">sudo kill</span> <span class="nt">-9</span> 1748765

<span class="c"># 批量删除进程</span>
<span class="nb">sudo </span>lsof <span class="nt">-ti</span> :7890 | xargs <span class="nb">sudo kill</span> <span class="nt">-9</span>

<span class="c"># 还可以尝试这个，只是需要 sudo apt-get install tcpkill</span>
<span class="nb">sudo </span>tcpkill <span class="nt">-i</span> lo port 7890
</code></pre></div></div>

<p>然后退出服务器重连即可。</p>

<p><br />
<br /></p>]]></content><author><name>Ni Mu</name><email>mn23@mails.tsinghua.edu.cn</email></author><category term="Python" /><category term="GitHub" /><category term="Linux" /><summary type="html"><![CDATA[通过 SSH RemoteForward，把本机的代理端口转发到远程服务器，让服务器也能走代理联网。]]></summary></entry><entry><title type="html">（已解决）MuJoCo · Metaworld︱RuntimeError: Failed to initialize OpenGL</title><link href="https://moonout.link/mujoco-opengl-runtimeerror-fix/" rel="alternate" type="text/html" title="（已解决）MuJoCo · Metaworld︱RuntimeError: Failed to initialize OpenGL" /><published>2024-08-11T00:00:00+08:00</published><updated>2024-08-11T00:00:00+08:00</updated><id>https://moonout.link/mujoco-opengl-runtimeerror-fix</id><content type="html" xml:base="https://moonout.link/mujoco-opengl-runtimeerror-fix/"><![CDATA[<p><br /></p>

<p>解决方案：在 bash 命令行执行</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">unset </span>LD_PRELOAD
</code></pre></div></div>

<p>参考链接：<a href="https://github.com/openai/mujoco-py/issues/187">https://github.com/openai/mujoco-py/issues/187</a></p>

<p><br />
<br /></p>]]></content><author><name>Ni Mu</name><email>mn23@mails.tsinghua.edu.cn</email></author><category term="MuJoCo" /><category term="Metaworld" /><category term="OpenGL" /><summary type="html"><![CDATA[解决 MuJoCo / Metaworld 报 RuntimeError: Failed to initialize OpenGL，在 bash 命令行执行 unset LD_PRELOAD。]]></summary></entry><entry><title type="html">Linux alias 配置：自定义常用命令的快捷形式</title><link href="https://moonout.link/linux-alias-config/" rel="alternate" type="text/html" title="Linux alias 配置：自定义常用命令的快捷形式" /><published>2024-07-31T00:00:00+08:00</published><updated>2024-07-31T00:00:00+08:00</updated><id>https://moonout.link/linux-alias-config</id><content type="html" xml:base="https://moonout.link/linux-alias-config/"><![CDATA[<p><br /></p>

<p>（这些配置是从组里同期那边 copy + 同学帮忙写的，仅存档自用；致谢同期和同学）</p>

<hr />

<p>（希望可以一连接服务器就使用 bash，可以先 cat /etc/shells 查看服务器有哪些可用 shell，然后 chsh -s /bin/bash 修改默认 shell 为 bash）</p>

<p>（gf 需要 pip install gpustat==1.1.1 ）</p>

<p>（tmux 开启滚动，echo “set -g mouse on” » ~/.tmux.conf ）</p>

<p>编辑 .bashrc ，添加</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># alias</span>
<span class="nb">alias </span><span class="nv">sb</span><span class="o">=</span><span class="s1">'source ~/.bashrc'</span>
<span class="nb">alias </span><span class="nv">vbrc</span><span class="o">=</span><span class="s1">'vim ~/.bashrc'</span>
<span class="nb">alias </span><span class="nv">cx</span><span class="o">=</span><span class="s1">'chmod +x'</span>

<span class="nb">alias </span><span class="nv">tb</span><span class="o">=</span><span class="s1">'tensorboard --logdir . --window_title $(pwd)'</span>
<span class="nb">alias </span><span class="nv">tbb</span><span class="o">=</span><span class="s1">'tensorboard --logdir . --window_title $(pwd) &amp;'</span>
<span class="nb">alias </span><span class="nv">tbp</span><span class="o">=</span><span class="s1">'tensorboard --logdir . --window_title $(pwd) --port'</span>

<span class="k">function </span>tbbp<span class="o">(){</span>
    tensorboard <span class="nt">--logdir</span> <span class="nb">.</span> <span class="nt">--window_title</span> <span class="si">$(</span><span class="nb">pwd</span><span class="si">)</span> <span class="nt">--port</span> <span class="nv">$1</span> &amp;
<span class="o">}</span>

<span class="nb">alias </span><span class="nv">pdg</span><span class="o">=</span><span class="s1">'ps -def | head -n 1; ps -def | grep'</span>
<span class="nb">alias </span><span class="nv">pag</span><span class="o">=</span><span class="s1">'ps -aux | head -n 1; ps -aux | grep'</span>

<span class="nb">alias </span><span class="nv">tat</span><span class="o">=</span><span class="s1">'tmux attach -t'</span>
<span class="nb">alias </span><span class="nv">tl</span><span class="o">=</span><span class="s1">'tmux ls'</span>
<span class="nb">alias </span><span class="nv">tn</span><span class="o">=</span><span class="s1">'tmux new-session -s'</span>
<span class="nb">alias </span><span class="nv">tk</span><span class="o">=</span><span class="s1">'tmux kill-session -t'</span>

<span class="nb">alias </span><span class="nv">du1</span><span class="o">=</span><span class="s1">'du -ch -d 1'</span>      <span class="c"># 当前目录磁盘占用</span>
<span class="nb">alias </span><span class="nv">dun</span><span class="o">=</span><span class="s1">'du -ch -d'</span>        <span class="c"># 当前目录磁盘占用（递归n层）</span>
<span class="nb">alias </span><span class="nv">du1g</span><span class="o">=</span><span class="s1">'du -ch -d 1 2&gt;&amp;1 | grep -v "cannot read directory"'</span>

<span class="nb">alias </span><span class="nv">ns</span><span class="o">=</span><span class="s1">'nvidia-smi'</span>
<span class="nb">alias </span><span class="nv">gf</span><span class="o">=</span><span class="s1">'gpustat -f'</span>
<span class="nb">alias </span><span class="nv">cca</span><span class="o">=</span><span class="s1">'conda activate'</span>
<span class="nb">alias </span><span class="nv">ccd</span><span class="o">=</span><span class="s1">'conda deactivate'</span>
<span class="nb">alias </span><span class="nv">cl</span><span class="o">=</span><span class="s1">'conda list'</span>
<span class="nb">alias </span><span class="nv">cel</span><span class="o">=</span><span class="s1">'conda env list'</span>
<span class="nb">alias </span><span class="nv">pl</span><span class="o">=</span><span class="s1">'pip list'</span>

<span class="nb">alias </span><span class="nv">cc</span><span class="o">=</span><span class="s1">'claude --continue'</span>
<span class="nb">alias </span><span class="nv">cr</span><span class="o">=</span><span class="s1">'claude --resume'</span>

<span class="nb">alias </span><span class="nv">clash</span><span class="o">=</span><span class="s2">"/home&lt;username&gt;/clash/clash &gt; /home&lt;username&gt;/clash/clash.log 2&gt;&amp;1 &amp; export http_proxy=http://127.0.0.1:7890; export https_proxy=http://127.0.0.1:7890"</span>
<span class="nb">alias </span><span class="nv">unclash</span><span class="o">=</span><span class="s2">"unset http_proxy; unset https_proxy; pkill -9 clash"</span>

<span class="nb">export </span><span class="nv">HF_ENDPOINT</span><span class="o">=</span>https://hf-mirror.com
</code></pre></div></div>

<p>然后 <code class="language-plaintext highlighter-rouge">source ~/.bashrc</code> 。</p>

<p><br />
<br /></p>]]></content><author><name>Ni Mu</name><email>mn23@mails.tsinghua.edu.cn</email></author><category term="Linux" /><category term="Bash" /><summary type="html"><![CDATA[一份常用的 Linux alias 配置存档，涵盖 tensorboard、tmux、conda、GPU 监控等常用命令的快捷形式。]]></summary></entry></feed>