Mendelevium
Diary
Drug Design
Field Knowledge
Academia
Yang
Biology
Physics
Free Energy
Machine Learning & AI
Active Learning
Basics
Boltz-2
Data
Generation
Interpretability
QSAR application
Representations
Mol2Image
Workflow & Agent
Molecular Dynamics
FF & Algorithm
Small Molecule
martini
water
Interaction
Modeling & Tools
QM
Sampling & Analysis
Allostery
Fundamental
Other
Specific Sytems
Enzyme Engineering
Fiber & LLPS
Membrane
orientation_penetration
Metal
Nano Polymers
Skin Permeation
Techniques
Linux
Python
Research
Web
about
Home
Contact
Copyright © 2025 Xufan Gao | Academic Research Blog
Home
> Techniques
A Bunch of Biophysics is Loading ...
Techniques
Linux 集群 CPU 频率检测:区分高负载与硬件超频
Linux 集群 CPU 频率检测:区分高负载与硬件超频 引言 在管理 Linux 计算集群时,我们经常会在 pestat 输出中看到一些节点的 CPU 负载异常高。例如下面的 pestat 输出显示了多个节点的状态: Hostname Partition Node Num_CPU CPUload Memsize Freemem Joblist State Use/Tot (15min) (MB) (MB) JobID User ... node1 multi+ alloc 48 48 49.07* 191895 158367 436066 mxy ... node2 multi+ alloc 48 48 49.00* 191898 157115 436116 mxy ... node10 single mix 8 128 111.63* 515641 408900 434722 gxf1212 ... node11 multi+ mix 122 128 97.99* 515641 461935 436055 xucx ... node12 multi mix 114 128 112.52* 515641 452336 435966 shizq ... node22 multi mix 126 128 114.80* 515621 452780 432502 wangtk ... 注意到 node10 的 15 分钟平均负载达到 111.63,但实际上只分配了 8 个 CPU 核心(128 个核心中的 8 个),而 node22 的负载为 114.80,分配了 126 个核心。这种现象常常引发关于“超频”的疑问。本文将系统性地分析 CPU 负载与频率监控的完整方法论,帮助管理员准确诊断集群状态。 两种不同的“超频”概念 在深入技术细节之前,我们需要明确区分两个经常被混淆的概念: 软件层面的高负载 这是指系统的 Load Average(平均负载)异常高,超出了正式分配的计算核心数。例如某个节点有 128 个 CPU 核心,但 SLURM 只分配了 8 个核心给作业,而系统负载却达到了 111.63。这并不等于“有 111 个核心正在满载计算”,而是表示在统计窗口内,处于可运行状态或不可中断睡眠状态(常见于 I/O 等待)的任务平均数很高。 造成软件层面高负载的常见原因包括失控进程进入死循环、用户运行高并行度程序(如使用 make -j 128 进行编译)、大量线程同时争抢 CPU、I/O 阻塞导致大量任务处于 D 状态,以及 Docker 或 Singularity 容器、日志轮转、备份任务等额外工作负载。严格来说,僵尸进程本身不会继续消耗 CPU,也通常不是高 load average 的直接原因;如果看到大量僵尸,更应排查其父进程管理是否异常。 硬件层面的超频 这是传统意义上的概念,指通过调整 BIOS/UEFI 或使用软件,人为将 CPU 运行频率提升到出厂默认频率以上。本文后续部分将重点讨论如何检测这种情况。 CPU 硬件频率检测流程 检测 CPU 是否存在硬件超频的核心思路是对比 CPU 的当前运行频率、内核当前策略上限,以及厂商公开规格中的基础频率和最大 boost 频率。如果观测到的频率长期超过厂商规格上限,才值得怀疑 BIOS/UEFI 或平台策略存在非常规设置;如果只是高负载,而频率仍在规格内,则通常不属于硬件超频问题。 完整检测流程图 flowchart TD A[开始检测 CPU 硬件超频] --> B{获取 CPU 基础信息} B --> B1["lscpu<br>查看型号与基础频率"] B --> B2["查阅官方规格<br>获取最大睿频理论值"] B1 --> C{获取当前实时频率} C --> C1["cpupower frequency-info<br>查看驱动与策略"] C --> C2["watch -n 1 cat /proc/cpuinfo<br>实时监控频率"] C --> C3["turbostat<br>x86 平台专业级监控"] C2 --> D["核心判断逻辑"] B2 --> D D --> E{当前频率持续高于厂商规格上限?} E -- 是 --> F["⚠️ 可能存在超频或读数异常"] E -- 否 --> G["✅ 频率仍在规格或策略范围内"] F --> H["深入排查"] H --> H1["检查 BIOS 设置"] H --> H2["排查超频软件"] G --> I["检测完成"] 关键检测命令详解 步骤一:获取 CPU 型号与官方规格 首先需要知道 CPU 的“出厂设定”: lscpu | grep -E "Model name:|CPU MHz:|CPU max MHz:|CPU min MHz:" 输出示例: Model name: Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz CPU MHz: 2500.000 CPU max MHz: 3500.0000 CPU min MHz: 800.0000 关键字段说明:Model name 中的 @ 2.00GHz 一般对应厂商标称基础频率;CPU max MHz 和 CPU min MHz 是 lscpu 从内核接口读取到的本机可见频率范围,常可作为本机策略或驱动视角下的参考上限与下限;CPU MHz 则是当前某个 CPU 的瞬时或近似瞬时频率读数。它们对排障很有用,但不应直接替代厂商规格表。 ⚠️ 重要提示:lscpu 显示的 CPU max MHz 来自内核当前暴露的信息,它可能受驱动、BIOS/UEFI、电源策略和平台实现影响,因此不一定等于厂商宣传页上的最大 boost 频率。最可靠的方法仍然是根据 CPU 型号去厂商官网查询正式规格。 步骤二:监控当前实时频率 查看 CPU 在负载下的实际运行频率有多种方法。使用 cpupower 工具可以查看详细的频率信息,包括 driver(当前 cpufreq 驱动)、hardware limits(内核当前看到的频率范围)、available frequency steps(可用的频率档位,若驱动支持)、boost state support(平台是否支持 boost,以及当前是否启用)以及 current CPU frequency。需要注意,current CPU frequency 的精度和含义依赖具体驱动与硬件接口,不能把它当作绝对精确的硬件测量值。 sudo cpupower frequency-info 动态监控所有核心(最直观的方法)是使用 watch 命令实时刷新显示频率: watch -n 1 "grep \"^[c]pu MHz\" /proc/cpuinfo" 这种方法直观、方便,而且 watch 的手册页也把它作为动态频率观察示例。但 /proc/cpuinfo 中的 cpu MHz 本质上是内核导出的软件读数,适合快速巡检,不适合拿来做极严格的频率取证。 使用 turbostat(专业级监控工具)可以获取更详细的性能数据: sudo turbostat --quiet --show Core,CPU,Busy%,Bzy_MHz,CPU%c7 --interval 2 其中 Bzy_MHz 列显示每个逻辑 CPU 在忙碌时的平均运行频率。turbostat 是 x86 平台的专业工具,在 Intel 平台上最常见;在 AMD 平台上通常也可使用,但具体字段可用性会受内核、处理器型号和权限影响。 实战案例分析 案例 1:node10 节点分析 环境信息: Model name: AMD EPYC 7713 64-Core Processor CPU MHz: 1500.000 CPU max MHz: 2000.0000 CPU min MHz: 1500.0000 cpupower 输出: analyzing CPU 0: driver: acpi-cpufreq hardware limits: 1.50 GHz - 2.00 GHz available frequency steps: 2.00 GHz, 1.70 GHz, 1.50 GHz current policy: frequency should be within 1.50 GHz and 2.00 GHz. The governor "conservative" may decide which speed to use within this range. current CPU frequency: 1.50 GHz (asserted by call to hardware) Error while evaluating Boost Capabilities on CPU 0 -- are you root? 实时监控结果:watch -n 1 "grep \"^[c]pu MHz\" /proc/cpuinfo" 显示各核心均为 1.50 GHz。 诊断结论 根据 AMD 官方规格,EPYC 7713 的基础频率为 2.0 GHz,最大 boost 频率可达 3.675 GHz。 这里最稳妥的判断顺序是三步: lscpu 显示 CPU MHz = 1500、CPU max MHz = 2000,说明当前内核看到的瞬时频率为 1.50 GHz,本机可见上限为 2.00 GHz。 cpupower frequency-info 显示 hardware limits: 1.50 GHz - 2.00 GHz,且当前策略为 conservative,current CPU frequency 也为 1.50 GHz。 /proc/cpuinfo 动态监控时,各核心频率持续稳定在 1.50 GHz,没有出现任何高于 2.00 GHz 的读数。 因此,“现有证据只能支持 node10 没有发生硬件超频”。更准确地说,这台机器当前运行在 1.50 GHz 的低频状态,而不是跑到了超出规格的高频状态。 至于为什么这颗 7713 没有表现出更高的 boost 频率,则是另一个问题。当前输出只能说明 Linux 通过 acpi-cpufreq 暴露给用户空间的范围是 1.50 至 2.00 GHz,不能仅凭这一点就断言“boost 一定被彻底禁用”。更合理的说法是:这个节点目前处于较保守的频率策略下,或者平台没有把更高 boost 档位暴露给当前的 cpufreq 接口。 案例 2:node22 节点分析 环境信息: Model name: AMD EPYC 7763 64-Core Processor CPU MHz: 2450.000 CPU max MHz: 2450.0000 cpupower 输出: hardware limits: 1.50 GHz - 2.45 GHz current CPU frequency: 2.45 GHz Error while evaluating Boost Capabilities turbostat 输出: Busy% Bzy_MHz 100.00 3099 100.00 3123 100.00 3145 ... 在满负载核心上,Bzy_MHz 多次出现在约 3.05 至 3.15 GHz 的区间。 诊断结论 根据 AMD 官方规格,EPYC 7763 的基础频率为 2.45 GHz,最大 boost 频率约 3.5 GHz。 这里同样按证据链来判断: lscpu 显示 CPU MHz = 2450、CPU max MHz = 2450、CPU min MHz = 1500。 cpupower frequency-info 显示 hardware limits: 1.50 GHz - 2.45 GHz,当前调速器仍为 conservative,current CPU frequency 为 2.45 GHz。 /proc/cpuinfo 动态监控时,各核心持续稳定在 2.45 GHz,没有看到高于 2.45 GHz 的读数。 但 turbostat 在高负载下给出的 Bzy_MHz 多次达到约 3.1 GHz,明显高于 2.45 GHz,但仍低于 AMD 官方标称的最大 boost 频率 3.5 GHz。 因此,现有证据支持的结论是:node22 没有发生硬件超频,而且实际上已经进入了正常的 boost 区间。换句话说,lscpu、cpupower 和 /proc/cpuinfo 这几处在这台老内核机器上更像是在报告 cpufreq 接口可见的基础档或策略档,而 turbostat 则揭示了核心忙碌时的实际平均运行频率。 需要强调的是,AMD 官网给出的 3.5 GHz 是厂商标称的最大 boost 频率,而不是此时 Linux acpi-cpufreq 接口已经向用户空间暴露出来的可用上限。node22 的 turbostat 结果说明:当前 Linux 可见的 cpufreq 上限未体现出厂商标称的 boost 档位,但 boost 本身并不一定没开。 两个节点的对比 对比项 node10 node22 CPU 型号 AMD EPYC 7713 AMD EPYC 7763 官方基础频率 2.0 GHz 2.45 GHz 当前运行频率 1.5 GHz 2.45 GHz cpupower 可见范围 1.50-2.00 GHz 1.50-2.45 GHz turbostat 观测 暂无补充数据 忙碌核心约 3.05-3.15 GHz 频率状态 低于基础频率的低频运行 实际可进入高于基础频率的正常 boost 区间 Boost 暴露情况 cpufreq 未显示高于基础频率的 boost 上限 cpufreq 未显示 boost 上限,但 turbostat 已观察到 boost 硬件超频 ❌ 否 ❌ 否 总结与建议 检测要点总结 检测 CPU 超频的核心在于区分两类不同概念:软件高负载与硬件超频是两回事,前者通常意味着可运行任务或 I/O 等待任务太多,后者才是实际运行频率超过硬件规格。更稳妥的判定流程是:先看 lscpu,再看 cpupower frequency-info 的驱动、策略和可见频率范围,最后用 /proc/cpuinfo 或 turbostat 做动态复核。尤其是在老内核加 acpi-cpufreq 的组合下,lscpu 和 cpupower 可能看不到完整 boost 档位,这时应优先相信 turbostat 给出的忙碌频率,再去和厂商规格比较。只要观测频率没有超过厂商规格上限,就不能把它判定为超频。 关键命令组合: # 快速检查 lscpu | grep -E "Model name:|CPU max MHz:" # 详细监控 sudo cpupower frequency-info watch -n 1 "grep \"^[c]pu MHz\" /proc/cpuinfo" 管理建议 根据不同的应用场景和管理需求,我们提供以下管理建议: 场景类型 建议措施 说明 性能敏感的应用 检查 BIOS 设置、平台电源策略与 cpufreq 驱动类型;确认是否启用了 boost 相关能力;再评估是否需要将 CPU 调速器从 conservative 改为 performance 最大化 CPU 性能输出 稳定性和能效优先 当前配置是合理的,牺牲部分峰值性能换取稳定性;定期监控系统负载,确保没有失控进程 适合长期稳定运行 集群统一管理 建议对同类节点使用一致的 BIOS 和电源策略;建立基准测试,验证不同配置下的实际性能差异 便于运维和管理 如果还要继续追问“为什么没有 boost” 上面的命令已经足够支持“不是超频”这个结论。如果后续还想解释“为什么没看到 3.5 GHz 或 3.675 GHz”,则建议补充以下命令,进一步区分是 BIOS 设置、驱动类型,还是 cpufreq 策略导致的: cat /sys/devices/system/cpu/cpufreq/policy0/scaling_driver cat /sys/devices/system/cpu/cpufreq/policy0/scaling_governor cat /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq cat /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq cat /sys/devices/system/cpu/cpufreq/boost 如果系统支持,还可以继续看: dmesg | grep -i amd_pstate dmesg | grep -i cpufreq sudo turbostat --quiet --show Core,CPU,Busy%,Bzy_MHz --interval 2 对于 node22,uname -r 显示的是 3.10.0-957.el7.x86_64,dmesg 中可见的是 acpi_cpufreq,而没有 amd_pstate。这说明它运行在较老的内核和传统 cpufreq 驱动栈上,这也正好解释了为什么 cpupower 没有把 boost 能力展示完整,而 turbostat 仍然能观察到约 3.1 GHz 的实际忙碌频率。 因此,这些命令不是为了重新证明“有没有超频”,而是为了回答另一个更细的问题:为什么当前平台没有把更高 boost 档位完整暴露出来,或者为什么不同工具看到的频率上限不一致。 参考资源 Linux Kernel CPU Frequency Scaling:https://www.kernel.org/doc/html/latest/admin-guide/pm/cpufreq.html Linux Kernel amd-pstate 文档:https://docs.kernel.org/admin-guide/pm/amd-pstate.html lscpu 手册页:https://man7.org/linux/man-pages/man1/lscpu.1.html uptime 手册页:https://man7.org/linux/man-pages/man1/uptime.1.html proc_loadavg 手册页:https://man7.org/linux/man-pages/man5/proc_loadavg.5.html procps 手册页(僵尸进程与进程状态):https://man7.org/linux/man-pages/man1/procps.1.html AMD EPYC 处理器官方规格:https://www.amd.com/en/products/cpu/amd-epyc-7003-series cpupower 手册页:https://man7.org/linux/man-pages/man1/cpupower-frequency-info.1.html watch 手册页:https://man7.org/linux/man-pages/man1/watch.1.html turbostat 手册页:https://man.archlinux.org/man/turbostat.8.en
Techniques
· 2026-03-16
Agent Reach:让AI助手访问互联网的超简单方法
Agent Reach:让AI助手访问互联网的超简单方法 什么是Agent Reach Agent Reach是一个开源工具包,能让Claude等AI助手直接访问互联网。通过它,AI可以读取GitHub代码、提取YouTube字幕、搜索推文、浏览网页等,而不再局限于训练数据中的旧信息。 能做什么 安装后,AI助手可以: GitHub:读取代码、搜索仓库、查看Issue和PR YouTube:提取视频字幕和元数据 Twitter/X:搜索和阅读推文 网页:将任意网页转为Markdown格式 语义搜索:全网智能搜索(免费,无需API) RSS订阅:追踪博客和新闻更新 B站:提取视频信息和字幕 微信公众号:搜索和阅读公众号文章 超简单的安装方法 安装Agent Reach非常简单,只需要一句话。 根据官方文档,安装方式很直接: 把下面这句话复制给你的AI Agent就行: 帮我安装 Agent Reach:https://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/install.md AI会自己去读文档、装依赖、配环境,几分钟搞定。 手动安装步骤 如果你想手动安装,只需3条命令: # 1. 安装Agent Reach核心包 pip install https://github.com/Panniantong/agent-reach/archive/main.zip # 2. 安装mcporter(MCP服务器管理工具) npm install -g mcporter # 3. 配置Exa语义搜索(免费) mcporter config add exa https://mcp.exa.ai/mcp 检查安装状态 安装完成后,运行: agent-reach doctor 这个命令会显示每个渠道的状态:哪个通、哪个不通、怎么修,一目了然。 正常情况下,你会看到类似这样的输出: Agent Reach 状态 ======================================== ✅ 装好即用: ✅ GitHub 仓库和代码 — 完整可用 ✅ YouTube 视频和字幕 — 可提取 ✅ RSS/Atom 订阅源 — 可读取 ✅ 全网语义搜索 — 可用(免费) ✅ 任意网页 — 通过 Jina Reader 搜索渠道: ✅ Twitter/X 推文 — 完整可用 ✅ B站视频和字幕 — 可提取 配置后可用: ✅ 微信公众号文章 — 完整可用(搜索 + 阅读公众号文章) 状态:8/14 个渠道可用 安装细节说明 系统要求 Python:3.8或更高版本 Node.js:16或更高版本 网络:某些服务可能需要代理(如Reddit、Twitter在国内) 安装位置 所有工具都安装在用户级别,不需要sudo权限: Python包:通过pip安装到用户环境 npm包:通过npm全局安装到用户目录 配置文件:存储在~/.config/mcporter/或项目目录下 如果遇到问题 如果某些渠道显示不可用,agent-reach doctor会给出具体提示: Reddit被封: agent-reach configure proxy http://user:pass@ip:port 微博未配置: pip install git+https://github.com/Panniantong/mcp-server-weibo.git mcporter config add weibo --command 'mcp-server-weibo' 小红书未配置(需要Docker): docker run -d --name xiaohongshu-mcp -p 18060:18060 xpzouying/xiaohongshu-mcp mcporter config add xiaohongshu http://localhost:18060/mcp 微信公众号未配置: # 阅读文章(URL → Markdown) pip install camoufox[geoip] markdownify beautifulsoup4 httpx mcp # 搜索文章(关键词 → 文章列表) pip install miku_ai 实际使用示例 安装完成后,你可以直接让AI助手帮你做这些事: 示例1:YouTube学习(真实测试) 以提取YouTube视频信息为例: 用户:提取这个YouTube视频的信息和字幕: https://www.youtube.com/watch?v=HC81oYe43DI AI:[通过Agent Reach调用YouTubeChannel] [使用yt-dlp后端提取视频元数据] [获取字幕文件] [解析并整理内容] 🔍 Agent Reach检测结果: ✅ YouTube频道可用:youtube(使用yt-dlp后端) ✅ 视频URL格式正确 ❌ 网络连接失败:Connection refused 测试环境: - yt-dlp版本:2026.03.03 - 网络状态:无法直接访问YouTube(需代理) 测试结果:Agent Reach的YouTube功能已正确安装(yt-dlp 2026.03.03),但在国内网络环境下需要配置代理才能使用。 解决方案: # 配置代理以访问YouTube agent-reach configure proxy http://user:pass@ip:port # 或从浏览器提取YouTube cookies agent-reach configure youtube-cookies --from-browser chrome 配置后即可正常提取YouTube视频信息和字幕,支持多语言字幕自动下载。 示例2:网页阅读 以总结Jerkwin博客的GROMACS教程文章为例: 用户:帮我总结这篇文章: https://jerkwin.github.io/2016/05/31/GROMACS%E8%BD%A8%E8%BF%B9%E5%91%A8%E6%9C%9F%E6%80%A7%E8%BE%B9%E7%95%8C%E6%9D%A1%E4%BB%B6%E7%9A%84%E5%A4%84%E7%90%86/ AI:[通过Agent Reach调用WebChannel] [使用Jina Reader后端提取内容] [解析返回的Markdown] [提炼核心技术要点] 📄 文章标题:GROMACS轨迹周期性边界条件的处理|Jerkwin 🔗 来源:https://jerkwin.github.io/... 📝 整理:刘世恩;补充:李继存(2016-05-31) ✅ Agent Reach成功提取:4581个字符 核心内容总结: 主题:GROMACS轨迹周期性边界条件(PBC)的处理 主要工具: ✅ gmx trjconv:GROMACS处理PBC的主要工具 ✅ VMD的pbc命令:可视化时修正PBC效果 处理步骤(完整命令): 1. 使分子保持完整: gmx trjconv -s npt.tpr -f prod.xtc -o prod_whole.xtc -pbc whole 2. 选择中心原子进行居中: gmx trjconv -s npt.tpr -f prod_whole.xtc -n index.ndx \ -o prod_atom_center.xtc -pbc atom -center 3. 如需叠合去除平动和转动: gmx trjconv -s npt.tpr -f prod_atom_center.xtc \ -o prod_atom_center_fit.xtc -fit rot+trans 关键参数说明: ⚠️ -pbc atom:最通用,适用于所有情况 ⚠️ -pbc res:用于生物分子(按残基处理) ⚠️ -pbc mol:仅在拓扑文件中单独定义分子时有效 ⚠️ 中心原子选择:应选分子近似中心的原子 ⚠️ 盒子大小建议:3-5 nm以避免处理困难 VMD替代方案: pbc wrap -compound res -all pbc box 测试结果:Agent Reach成功通过WebChannel读取了完整的博客文章,自动处理了URL编码,提取了4581个字符的内容,保留了代码块、技术要点等关键信息。AI助手无需关心底层实现,直接通过Agent Reach的统一接口即可获取干净的Markdown内容。 示例3:微信公众号搜索 以搜索”GROMACS 2026.0更新”为例,AI助手可以: 用户:搜索关于"GROMACS 2026.0更新"的公众号文章 AI:[使用miku_ai搜索微信公众号] [找到4篇相关文章] [提取第一篇文章内容] 搜索结果: 1. 《GROMACS 2026.0:NN势函数、GPU加速与AMBER/PLUMED完整支持》 2. 《Gromacs蛋白质结构模拟入门简明步骤更新》 3. 《[工具]GROMACS分子动力学模拟流程实战(自用)》 4. 《又更新了 gromacs基础技能讲解系列教程上线》 文章要点总结: ✅ 神经网络势函数接口:原生支持DeepMD、ANI等ML势模型 ✅ AMD GPU完整HIP后端:所有主要内核均支持AMD GPU ✅ NVIDIA GPU自由能计算加速:FEP/TI性能提升10-30% ✅ AMBER力场完整验证:支持ff19SB、OL3等最新力场 ✅ PLUMED 2.9集成:增强采样功能更加稳定 ✅ QM/MM稳定性改进:引入检查点机制 测试结果:微信公众号功能完全可用,成功搜索并提取了最新的技术文章内容。首次使用camoufox需要下载约700MB的浏览器(约2-3分钟),后续使用会快很多。 示例4:GitHub仓库搜索 以搜索”molecular dynamics”相关仓库为例: 用户:搜索GitHub上关于"molecular dynamics"的热门仓库 AI:[使用GitHub API搜索仓库] [按星标数排序] [提取前5个结果] 搜索结果(共找到4802个仓库): 1. deepmodeling/deepmd-kit 描述:A deep learning package for many-body potential energy representation and molecular dynamics Stars:1887 | Forks:598 链接:https://github.com/deepmodeling/deepmd-kit 2. MDAnalysis/mdanalysis 描述:MDAnalysis is a Python library to analyze molecular dynamics simulations Stars:1546 | Forks:807 链接:https://github.com/MDAnalysis/mdanalysis 3. jax-md/jax-md 描述:Differentiable, Hardware Accelerated, Molecular Dynamics Stars:1389 | Forks:233 链接:https://github.com/jax-md/jax-md 4. brucefan1983/GPUMD 描述:Graphics Processing Units Molecular Dynamics Stars:735 | Forks:175 链接:https://github.com/brucefan1983/GPUMD 5. mdtraj/mdtraj 描述:An open library for the analysis of molecular dynamics trajectories Stars:705 | Forks:291 链接:https://github.com/mdtraj/mdtraj 测试结果:GitHub搜索功能完全可用。虽然系统自带的gh CLI版本较旧(2.4.0),但可以直接通过GitHub API实现搜索功能,获取仓库信息、星标数、描述等完整数据。 核心优势 极简安装:一句话搞定,AI自主完成所有配置 开箱即用:8个主流渠道无需额外配置(包括微信公众号) 统一接口:基于MCP协议的标准化设计 开源免费:完全开源,社区驱动 隐私安全:数据在本地处理,不依赖第三方AI服务 相关资源 Agent Reach GitHub:https://github.com/Panniantong/agent-reach 安装文档:https://github.com/Panniantong/agent-reach/blob/main/docs/install.md MCP协议:https://modelcontextprotocol.io/ 使用指南:运行agent-reach setup查看交互式配置
Techniques
· 2026-03-10
生物物理学MCP服务器推荐:让AI成为科研的得力助手
生物物理学MCP服务器推荐:让AI成为科研的得力助手 什么是MCP(Model Context Protocol) 模型上下文协议(Model Context Protocol,MCP)是Anthropic于2024年11月推出的开放标准,它定义了AI模型与外部工具或资源之间统一的双向通信协议。简单来说,MCP就像是给AI装上了“工具插件”,让它能够直接访问数据库、运行计算、调用API等,而不仅仅是根据训练数据生成回答。 对于生物物理学和计算化学研究者来说,MCP带来了以下突破: 无缝数据访问:AI可以直接从PubMed、arXiv、UniProt等数据库获取最新文献和蛋白质数据 实时计算能力:在超算平台(如NERSC的Perlmutter)上运行分子动力学模拟 智能工具编排:AI助手可以自动调用合适的工具完成复杂的研究任务 快速原型验证:系统生物学中的机理模型可以以前所未有的速度进行构建和测试 Lawrence Berkeley国家实验室的研究人员已经使用MCP连接了NERSC API、光束线知识库和X射线数据库,实现了从数据获取到超算计算的全流程自动化。 使用 Anthropic Life Sciences 插件市场 Anthropic 官方维护了一个专门的生命科学插件市场,包含多个预配置的 MCP 服务器和技能(skills),可以一键安装。 添加插件市场 /plugin marketplace add https://github.com/anthropics/life-sciences.git 可用的生命科学插件 MCP 服务器: pubmed@life-sciences:PubMed 文献数据库访问 biorender@life-sciences:BioRender 科学图表制作 synapse@life-sciences:Sage Bionetworks Synapse 数据平台 wiley-scholar-gateway@life-sciences:Wiley 学术文献网关 benchling-mcp@life-sciences:Benchling 实验室信息管理 10x-genomics@life-sciences:10x Genomics 单细胞数据 技能(Skills): single-cell-rna-qc@life-sciences:单细胞RNA测序质控分析 安装示例 # 安装 PubMed 插件 /plugin install pubmed@life-sciences # 安装 Wiley Scholar Gateway /plugin install wiley-scholar-gateway@life-sciences # 安装 BioRender(科学图表制作) /plugin install biorender@life-sciences # 安装单细胞 RNA-seq 质控技能 /plugin install single-cell-rna-qc@life-sciences 验证插件安装 安装完成后,可以在 Claude Code 中直接使用: 请使用 PubMed 搜索关于 "CRISPR Cas9 off-target effects" 的最新文献 注意:插件市场的工具会自动添加到 Claude Code 的 MCP 配置中,无需手动编辑 mcp.json。 第三方mcp安装与配置步骤 前置要求 安装uv(Python包管理器): curl -LsSf https://astral.sh/uv/install.sh | sh 将uv添加到PATH(永久生效): echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc source ~/.bashrc 安装MCP服务器 让CLAUDE CODE自己装吧,把GitHub上的安装说明扔给它就行,要不然白学cc了,哈哈。codex同理。 配置Claude Code 编辑配置文件: nano ~/.claude/mcp.json # 对于Claude Code 添加服务器配置(参考下面的配置示例) 重启Claude Code使配置生效,可能需要退出terminal重开一个。 生物物理学研究的MCP服务器 具体介绍和安装说明详见GitHub。 一、文献数据库类 1. Reference MCP [GitHub:https://github.com/ndchikin/reference-mcp] 功能:从CiteAs和Google Scholar获取BibTeX格式的文献引用 可用工具: get_citeas_data:通过DOI、URL或关键词获取引用 get_scholar_data:搜索Google Scholar并返回BibTeX引用列表 安装方法: uv tool install reference-mcp 配置示例(添加到~/.claude.json): { "mcpServers": { "reference-mcp": { "command": "uvx", "args": ["reference-mcp"], "disabled": false } } } 实际应用:在写论文或综述时,AI可以自动获取所有引用文献的BibTeX格式,无需手动查找和格式化。 2. PubMed MCP [GitHub:https://github.com/andybrandt/mcp-simple-pubmed] 功能:访问PubMed生物医学文献数据库 核心工具: search_articles:支持关键词、作者、期刊、日期过滤的文献搜索 get_article_metadata:获取文章的标题、摘要、作者、DOI等详细信息 另有14个高级工具用于更复杂的PubMed操作 安装方法: uv tool install mcp-simple-pubmed 配置示例: { "pubmed": { "command": "uvx", "args": ["mcp-simple-pubmed"], "disabled": false } } 实际应用:研究角质层蛋白时,AI可以自动搜索“stratum corneum proteins intercellular space”相关的最新文献,并提取关键信息。 3. arXiv MCP GitHub:https://github.com/blazickjp/arxiv-mcp-server 功能:搜索和下载arXiv预印本 可用工具: search_papers:按关键词、分类(如cond-mat.soft、physics.chem-ph)搜索论文 download_paper:下载PDF文件到本地 list_papers:列出已下载的论文 read_paper:读取并提取论文内容 安装方法: uv tool install arxiv-mcp-server 配置示例: { "arxiv": { "command": "uvx", "args": [ "arxiv-mcp-server", "--storage-path", "~/research/arxiv_papers" ], "disabled": false } } 测试案例:搜索“coarse-grained molecular dynamics polymer self-assembly”,可以找到粗粒化分子动力学模拟聚合物自组装的相关预印本。 二、蛋白质结构与序列类 4. AlphaFold MCP [GitHub:https://github.com/Augmented-Nature/AlphaFold-MCP-Server] 功能:访问AlphaFold蛋白质结构预测数据库 核心能力: 通过UniProt ID检索结构预测 按蛋白名称或基因搜索可用结构 获取逐残基置信度分数(pLDDT) 分析置信度分布,识别高/低置信度区域 多格式下载(PDB、mmCIF) 安装方法: uv tool install alphafold-mcp-server 实际应用:研究角质层蛋白CDSN时,可以快速获取AlphaFold预测的三维结构,分析其与HA的潜在结合位点。 5. UniProt MCP [GitHub:https://github.com/TakumiY235/uniprot-mcp-server] 功能:访问UniProt蛋白质知识库 核心工具: 按名称、关键词、生物体搜索蛋白质 获取详细的蛋白质注释信息 检索氨基酸序列 多蛋白比较分析 安装方法: uv tool install uniprot-mcp-server 实际应用:快速获取Kallikrein 5/7、LL-37等角质层蛋白的序列信息和功能注释。 三、化学与药物发现类 6. PubChem MCP [GitHub:https://github.com/Augmented-Nature/PubChem-MCP-Server] 功能:访问超过1.1亿化合物的数据库 强大的10+工具: 子结构/超结构搜索 3D构象检索 Tanimoto相似性搜索 ADMET性质预测(吸收、分布、代谢、排泄、毒性) Lipinski规则评估 分子性质计算 安装方法: # 从GitHub安装(需要网络连接) uv tool install --from git+https://github.com/Augmented-Nature/PubChem-MCP-Server.git pubchem-mcp-server 实际应用:研究HA衍生物的渗透性时,可以预测其ADMET性质,筛选合适的化学修饰策略。 四、代码智能与开发辅助类 7. Context7 [npm:https://www.npmjs.com/package/@context7/mcp-server] 功能:实时代码文档查询 优势: 快速获取最新文档:比搜索引擎更精准 代码示例丰富:直接可用的代码片段 API文档完整:参数、返回值、用法详细说明 多库支持:Biopython、Uni-Mol、MDAnalysis等分子建模工具 配置示例(需要API密钥): { "context7": { "command": "npx", "args": ["-y", "@context7/mcp-server"], "env": { "CONTEXT7_API_KEY": "your-api-key-here" }, "disabled": false } } 实际应用:写GROMACS分析脚本时,AI可以自动查询MDAnalysis的最新API用法,避免查阅过时文档。 8. Serena [GitHub:https://github.com/oraios/serena] 功能:语义代码操作和IDE集成 核心工具: find_symbol:查找符号定义 find_referencing_symbols:查找所有引用 insert_after_symbol:智能插入代码 关键特性: 专为IDE内编码辅助优化 支持VSCode、Cursor、Cline等 使用语义理解而非grep式搜索 避免读取整个文件,提高效率 安装方法: uvx --from git+https://github.com/oraios/serena serena start-mcp-server \ --context ide-assistant \ --project-from-cwd 实际应用:在大型分子动力学分析代码库中,快速定位特定函数的定义和调用位置。 完整配置示例 以下是一个适用于生物物理学研究的完整MCP配置(~/.claude.json): { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@context7/mcp-server"], "env": { "CONTEXT7_API_KEY": "your-api-key-here" }, "disabled": false }, "arxiv": { "command": "uvx", "args": [ "arxiv-mcp-server", "--storage-path", "~/research/arxiv_papers" ], "disabled": false }, "reference-mcp": { "command": "uvx", "args": ["reference-mcp"], "disabled": false }, "pubmed": { "command": "uvx", "args": ["mcp-simple-pubmed"], "disabled": false }, "alphafold": { "command": "uvx", "args": ["alphafold-mcp-server"], "disabled": false }, "uniprot": { "command": "uvx", "args": ["uniprot-mcp-server"], "disabled": false }, "serena": { "command": "uvx", "args": [ "--from", "git+https://github.com/oraios/serena", "serena", "start-mcp-server", "--context", "ide-assistant", "--project-from-cwd" ], "disabled": false } } } 实际研究案例 案例1:角质层蛋白调研 研究目标:调研角质层细胞间隙中可能存在的蛋白质 MCP工作流: PubMed搜索:AI使用search_articles搜索“stratum corneum intercellular proteins” 文献引用:通过get_citeas_data获取关键文献的BibTeX引用 蛋白质信息:用UniProt MCP查询CDSN、KLK5/7、LL-37等蛋白的序列和功能 结构预测:通过AlphaFold MCP获取蛋白质三维结构 结果整理:AI自动整理成表格,包含28种蛋白的定位、功能、与HA的相互作用 时间节省:从2-3天的手动文献调研缩短到1-2小时的AI辅助调研。 案例2:分子动力学文献综述 研究目标:撰写关于角质层脂质双层的MD模拟综述 MCP工作流: arXiv搜索:搜索“stratum corneum lipid bilayer molecular dynamics” 论文下载:自动下载相关预印本PDF 内容提取:使用read_paper提取方法学细节和关键结论 引用管理:通过Reference MCP生成所有文献的BibTeX Context7辅助:查询GROMACS、LAMMPS等MD软件的最新用法 成果:快速掌握领域最新进展,避免遗漏重要文献。 其他API地址 可以直接告诉cc有这些API,让调研过程更自动化。比如想知道某蛋白的等电点但没查到,可以直接获取序列、写代码预测,一步完成。 UniProt REST:https://rest.uniprot.org/uniprotkb/{Acc}.json,快速获取任意蛋白的序列与注释。 RCSB PDB REST:https://data.rcsb.org/rest/v1/core/entry/{PDB_ID}提供文本摘要,https://files.rcsb.org/download/{PDB_ID}.pdb或.cif可直接下载结构,https://search.rcsb.org/rcsbsearch/v2/query支持POST JSON条件检索(分辨率、链类型等)。 PDBe API:https://www.ebi.ac.uk/pdbe/api/pdb/entry/molecules/{PDB_ID}返回链、序列、配体等详情,.../residue_listing/可遍历残基级信息。 AlphaFold DB:https://alphafold.ebi.ac.uk/api/prediction/{UniProt_ID}提供序列、pLDDT分布与下载链接。 GlyGen/GlyCosmos:https://api.glygen.org/protein/{UniProt_ID}可查询糖基化位点与实验证据。 GlyConnect:https://glyconnect.expasy.org/api/proteins/{ID}返回具体glycan结构(网络较慢,必要时重试)。 HGNC/OMIM/NCBI Gene:https://rest.genenames.org/fetch/symbol/{symbol}可获得HGNC核心信息,其他接口需注册或API key。 NCBI Entrez eutils:https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=protein&id=...返回蛋白摘要,efetch可抓取序列。 ENA Browser/Ensembl REST:https://rest.ensembl.org/sequence/id/{ENSEMBL_ID}?content-type=text/plain可获取DNA或蛋白序列。 化学与配体API:https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{CID}/JSON提供理化属性,https://files.rcsb.org/ligands/download/{Lig}.cif可下载配体结构。 总结 MCP协议的出现标志着科研AI助手从被动回答到主动工具调用的质的飞跃。对于生物物理学和计算化学研究者,合理配置MCP服务器可以: 大幅节省文献调研时间(从数天缩短到数小时) 提高数据获取准确性(直接从数据库获取,避免手动错误) 加速研究迭代速度(快速验证计算假设) 降低学习曲线(AI自动查询最新API文档) 随着MCP生态系统的不断成熟,更多专业科研工具将以MCP服务器的形式出现,真正实现“让AI成为每个研究者的虚拟博士后”的愿景。
Techniques
· 2025-12-24
Slurm 作业插队指南:QOS 优先级配置从入门到实战
Slurm 作业“插队”指南:QOS 优先级配置从入门到实战 本文基于实验室集群的真实运维经验整理,介绍如何通过 QOS(Quality of Service)机制管理作业优先级。 核心概念 QOS、Partition、Account 的关系 Slurm 调度涉及四个核心概念: Partition(分区):节点的逻辑分组,可限定允许的 Account 和 QOS Account(账户):项目或课题组标识,用于计费和权限控制 QOS(服务质量):影响优先级和资源限制的关键机制 Association(关联):User-Account-Partition-QOS 的组合,必须存在才能提交作业 关键公式: 作业总优先级 = PriorityWeightAge × Age因子 + PriorityWeightFairshare × Fairshare因子 + PriorityWeightQOS × (QOS Priority / 系统最高QOS Priority) + PriorityWeightPartition × Partition优先级 + PriorityWeightTRES × TRES因子 Priority=0 说明:Slurm 默认的 normal QOS 就是 Priority=0,这是基准值。作业可以正常运行,但不会从 QOS 获得额外优先级加成(QOS 因子为 0)。正值提升优先级,负值降低优先级。 环境检查 确认集群启用了 multifactor 调度: scontrol show config | grep -i Priority 实际输出示例(your_cluster): PriorityType = priority/multifactor PriorityWeightAge = 200 PriorityWeightFairShare = 100 PriorityWeightPartition = 500 PriorityWeightQOS = 500 PriorityWeightTRES = gres/gpu=2000 关键参数:PriorityWeightQOS=500 和 PriorityWeightTRES=gres/gpu=2000 表示 GPU 资源权重最高。 查看当前作业优先级各因子贡献: sprio -u username | head 实际输出示例: JOBID PARTITION USER PRIORITY SITE AGE FAIRSHARE PARTITION QOS TRES 123456 quick username 514 0 3 2 1 500 gres/gpu=9 123456 quick username 514 0 3 2 1 500 gres/gpu=9 解读:QOS 贡献了 500 分(使用 urgent QOS,Priority=200,归一化后 × 500),TRES 贡献 9 分(申请了 GPU)。 创建 urgent QOS 检查现有 QOS sacctmgr show qos format=Name,Priority,MaxTRES,MaxWall,MaxJobsPU | column -t 实际输出示例: Name Priority MaxTRES MaxWall MaxJobsPU normal 0 - 64 multi 0 7-00:00:00 14 single 0 cpu=1,gres/gpu+ 7-00:00:00 100 quick 0 12:00:00 120 urgent 200 - - 可以看到 urgent QOS 的 Priority=200,明显高于其他 QOS 的 0。 创建并设置参数 sacctmgr add qos urgent \ priority=200 \ MaxJobsPU=200 \ MaxSubmitPU=200 \ MaxWall=02:00:00 \ MaxTRESPU=gres/gpu=4 参数说明: priority=200:QOS 优先级值,会被归一化后参与计算 MaxJobsPU:Per User,每用户最多运行作业数 MaxSubmitPU:Per User,每用户最多提交作业数 MaxWall:最长运行时间 MaxTRESPU:Per User,每用户最多 GPU 数 修改 QOS(可选): # 调整优先级 sacctmgr modify qos urgent set priority=300 # 设置组级别限制(所有用户共享) sacctmgr modify qos urgent set GrpTRES=gres/gpu=32 GrpJobs=12 配置 Partition 白名单 检查分区配置: scontrol show partition quick | egrep 'Allow|Default' 实际输出示例: AllowGroups=ALL AllowAccounts=project_a AllowQos=ALL 说明 quick 分区允许所有 QOS(AllowQos=ALL),但只允许 project_a 账户。 如果分区的 AllowQos 不是 ALL 且缺少 urgent,需要添加: scontrol update PartitionName=urgent AllowQos=urgent,normal AllowAccounts=urgent,project_a 授权用户使用 urgent 添加权限并设置默认 # 授权用户 sacctmgr modify user where name=username set qos+=urgent # 设置默认 QOS和账户,最好做一下 sacctmgr modify user where name=username set DefaultQOS=urgent sacctmgr modify user name=username set DefaultAccount=urgent 验证授权 sacctmgr show assoc where user=username format=User,DefaultQOS,QOS 实际输出示例: User Def QOS QOS username urgent normal,urgent username urgent normal,urgent 说明用户已被授权使用 urgent QOS,且默认 QOS 为 urgent。 提交测试作业并检查优先级: sbatch --partition=quick --qos=urgent --wrap="sleep 60" sprio -u username | head 应该看到 QOS 列出现 500 分(= PriorityWeightQOS × 归一化因子)。 解决 Invalid account 错误 问题诊断 错误信息:Invalid account or account/partition combination specified 原因:Slurm 要求 (Account, Partition) 组合必须在 Association 表中存在。 排查步骤 1. 检查默认账户 sacctmgr show user username format=User,DefaultAccount 如果默认账户不是 urgent,需要设置: sacctmgr modify user name=username set DefaultAccount=urgent 2. 检查 Association 是否存在 sacctmgr show assoc where user=username format=Cluster,Account,User,Partition,QOS 如果缺少 account=urgent, partition=urgent 的记录: sacctmgr add assoc user=username account=urgent partition=urgent 3. 检查分区允许的账户 scontrol show partition urgent | grep AllowAccounts 确保你的账户在允许列表中。 作业提交与验证 首次提交(显式指定所有参数) sbatch --partition=urgent --account=urgent --qos=urgent --time=10:00 --wrap="hostname" 简化提交(使用默认值) 如果已设置 DefaultAccount=urgent 和 DefaultQOS=urgent: sbatch --partition=urgent --time=10:00 --wrap="hostname" 迁移已提交的 Pending 作业 如果作业已提交到 quick 分区,想迁移到 urgent 分区提升优先级: # 错误做法(只改 Partition) scontrol update JobId=123456 Partition=urgent # 报错:Invalid account or account/partition combination specified # 正确做法(同时更新 Account 和 Partition) scontrol update JobId=123456 Account=urgent Partition=urgent 原因:urgent 分区只允许 urgent 账户(AllowAccounts=urgent),而原作业的账户是 project_a,必须一起更新才能匹配。 批量迁移多个作业: for jobid in $(squeue -u $USER -t PD -h -o "%i"); do scontrol update JobId=$jobid Account=urgent Partition=urgent done 验证迁移结果: scontrol show job 123456 | grep -E 'Account|Partition|Priority' 迁移成功后,优先级会显著提升(如从 520 → 1104)。 检查 QOS 限制 sacctmgr show qos urgent format=Name,MaxTRES,MaxJobsPU,MaxWall 常见 Pending 原因: QOSMaxJobsPerUserLimit:超过 MaxJobsPU QOSMaxGRESPerUser:超过 MaxTRESPU 的 GPU 限制 QOSMaxWallDurationPerJobLimit:申请时间超过 MaxWall 故障排查流程 graph TB A[作业提交失败] --> B{错误类型} B -->|Invalid account| C[检查 DefaultAccount<br/>sacctmgr show user] B -->|Invalid QOS| D[检查 QOS 授权<br/>sacctmgr show assoc] B -->|QOSMaxJobsPerUserLimit| E[检查作业数限制<br/>squeue -u xxx -t R] C --> C1{DefaultAccount 正确?} C1 -->|否| C2[设置 DefaultAccount=urgent] C1 -->|是| C3[检查 Association<br/>是否存在 account+partition] C3 --> C4[sacctmgr add assoc] D --> D1{QOS 列包含 urgent?} D1 -->|否| D2[sacctmgr modify user<br/>set qos+=urgent] D1 -->|是| D3[检查 QOS 是否存在<br/>sacctmgr show qos] E --> E1[检查 MaxJobsPU<br/>和当前运行作业数] E1 --> E2{超过限制?} E2 -->|是| E3[等待作业完成或<br/>联系管理员] E2 -->|否| E4[检查其他限制<br/>如 MaxTRES] 常见问题 Q1:sprio 显示 QOS 列为 0? 可能原因: QOS 的 Priority=0(基准值,无额外加成) PriorityWeightQOS=0(系统未启用 QOS 权重) 作业未使用目标 QOS 解决: # 检查并提升 QOS Priority sacctmgr show qos urgent format=Name,Priority sacctmgr modify qos urgent set priority=200 # 检查系统权重 scontrol show config | grep PriorityWeightQOS # 确认作业使用的 QOS scontrol show job 123456 | grep QOS Q2:设置了 DefaultQOS 但不生效? 原因:分区的 DefaultQOS 会覆盖用户设置,或脚本中显式指定了其他 QOS。 解决: scontrol show partition your_partition | grep DefaultQOS grep "qos" your_script.sh Q3:如何临时降低作业优先级? 使用 low QOS 或修改 Nice 值: sbatch --qos=low --wrap="sleep 60" # 或 scontrol update JobId=123456 Nice=10000 Q4:查看 QOS 使用情况? sacctmgr show qos format=Name,GrpJobs,GrpTRES,MaxJobsPU,MaxTRESPU -p squeue -o "%.10i %.9P %.8j %.8u %.2t %.10M %.6D" | head 实际输出示例: Name|GrpJobs|GrpTRES|MaxJobsPU|MaxTRESPU| normal|||64|gres/gpu=64| multi|500||14|gres/gpu=100| single|500||100|gres/gpu=150| quick|999||120|gres/gpu=200| urgent||||| JOBID PARTITION NAME USER ST TIME NODES 123456 multi ha-110_2 username R 43:46 1 123456 multi ha-110_2 username R 57:46 1 回滚与清理 移除用户授权 如果之前为使用 urgent 配置了专门的账户和 QOS,回滚时需要全部恢复: # 1. 移除默认 QOS sacctmgr modify user where name=username set DefaultQOS=normal # 2. 恢复默认账户(如果之前改过) sacctmgr modify user where name=username set DefaultAccount=project_a # 3. 取消 QOS 授权 sacctmgr modify user where name=username set qos-=urgent # 4. 验证清理结果 sacctmgr show assoc where user=username format=User,DefaultAccount,DefaultQOS,QOS 期望输出: User DefaultAccount Def QOS QOS username project_a normal normal 删除 QOS(谨慎) 检查是否有用户在使用: sacctmgr show assoc format=User,QOS | grep urgent 确认无人使用后删除: sacctmgr delete qos where name=urgent 建议保留 urgent QOS 供未来复用,只需取消用户授权即可。 总结 Slurm QOS 配置的关键步骤: 确认 PriorityType=priority/multifactor 已启用 创建 QOS 并设置 Priority 和资源限制 配置 Partition 允许该 QOS 授权用户并设置默认 QOS 确保 (Account, Partition) 组合存在于 Association 使用 sprio 验证优先级变化 掌握这些要点后,你可以灵活应对各种作业调度需求。
Techniques
· 2025-12-02
【实战教程】使用 frp 实现内网穿透:从零搭建安全的远程访问方案
【实战教程】使用 frp 实现内网穿透:从零搭建安全的远程访问方案 背景与需求 使用场景 在科研开发或远程协作中,我们经常需要: 在实验室内网服务器上运行 Web 应用(如 Streamlit、Jupyter 等) 让外部协作者能够访问这些服务进行测试和使用 通过 SSH 远程访问内网服务器进行开发调试 面临的问题 内网服务器无公网 IP,外网无法直接访问 公网 IP 动态变化,连接不同网络后 IP 会改变 需要安全的访问控制,不能完全暴露在公网 解决方案:frp 内网穿透 使用 frp(Fast Reverse Proxy) 通过一台有公网 IP 的云服务器(如 AWS EC2)作为中转。 架构图 graph LR A[外部访问者<br/>协作者电脑] -->|HTTP请求<br/>需要登录| B[Nginx<br/>HTTP Auth] B -->|认证通过| C[frps<br/>云服务器] C -->|frp隧道<br/>Token认证| D[frpc<br/>内网服务器] D -->|转发| E[Web应用<br/>本地服务] style A fill:#e1f5e1 style B fill:#ffe4e1,stroke:#333,stroke-width:2px style C fill:#ff9,stroke:#333,stroke-width:2px style D fill:#9cf,stroke:#333,stroke-width:2px style E fill:#9f9,stroke:#333,stroke-width:2px 核心架构: frps(服务端):运行在云服务器,有固定公网 IP frpc(客户端):运行在内网服务器,主动连接 frps Token 认证:保证只有授权的客户端能连接 Nginx 反向代理:添加 HTTP 密码保护层 端口映射: 云服务器:8502 → 内网:8502 (Web 应用) 云服务器:8606 → 内网:22/606 (SSH) 本文档包含: 完整的部署流程(含一键脚本) 实际遇到的问题和解决方法 安全配置策略(Token + HTTP Auth) WebSocket 支持(适用于 Streamlit 等) 快速索引 安全配置策略 云服务器端配置 内网客户端配置 HTTP 密码保护 完整部署流程 常见问题排查 安全配置策略(必读) 问题:内网服务器 IP 会变化怎么办? 推荐方案:使用 0.0.0.0/0 开放 frp 控制端口 + 强 Token 认证 为什么这样安全? Token 认证机制:即使攻击者能连接控制端口,没有正确的 Token 也会被拒绝 分层防护: frp 控制端口(7000):0.0.0.0/0 + 64位随机Token 实际服务端口(8502等):可限制为特定IP或通过Nginx认证 Token 强度:64 位十六进制字符串(256位熵),暴力破解几乎不可能 云服务器安全组配置(推荐) 类型 协议 端口 源地址 说明 Custom TCP TCP 7000 0.0.0.0/0 frp控制端口(Token认证) HTTP TCP 80 0.0.0.0/0 或 指定IP Nginx HTTP认证 Custom TCP TCP 8606 指定IP/32 SSH转发(可选) SSH TCP 22 你的IP/32 云服务器管理 重要:配置 Nginx 后,可以关闭 8502/8500/8504 等应用端口的直接访问,强制所有流量通过 Nginx 的密码保护。 生成强 Token # 在任意 Linux/macOS 机器上执行 openssl rand -hex 32 # 示例输出(每次运行都不同,请使用你自己生成的): # a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456 重要:生成后妥善保存,需要在云服务器和内网服务器两边同时使用! 1. 云服务器端配置(frps) 1.1 下载 frp # SSH 登录到云服务器 ssh your_user@YOUR_SERVER_IP # 下载 frp(以 0.65.0 为例,请访问 https://github.com/fatedier/frp/releases 获取最新版本) wget https://github.com/fatedier/frp/releases/download/v0.65.0/frp_0.65.0_linux_amd64.tar.gz # 解压 tar -xzf frp_0.65.0_linux_amd64.tar.gz cd frp_0.65.0_linux_amd64 1.2 一键部署脚本 #!/bin/bash # 文件名: deploy_frps.sh # 在云服务器上执行 set -e # 生成强随机 Token(如果已有 Token,可以直接替换下面这行) TOKEN=$(openssl rand -hex 32) echo "=========================================" echo "生成的 Token(请妥善保存,客户端需要使用):" echo "${TOKEN}" echo "=========================================" FRP_VERSION="0.65.0" FRP_DIR="$HOME/frp_${FRP_VERSION}_linux_amd64" # 下载并安装 frp cd ~ wget https://github.com/fatedier/frp/releases/download/v${FRP_VERSION}/frp_${FRP_VERSION}_linux_amd64.tar.gz tar -xzf frp_${FRP_VERSION}_linux_amd64.tar.gz cd ${FRP_DIR} # 创建服务端配置 cat > frps.toml <<EOF # frps 服务端配置 bindAddr = "0.0.0.0" bindPort = 7000 # Token 认证(必须与客户端一致) auth.method = "token" auth.token = "${TOKEN}" # 安全增强配置 transport.maxPoolCount = 5 transport.heartbeatTimeout = 90 # 日志配置 log.to = "./frps.log" log.level = "info" log.maxDays = 7 # Dashboard(可选,建议生产环境关闭) # webServer.addr = "0.0.0.0" # webServer.port = 7500 # webServer.user = "admin" # webServer.password = "change_this_password" EOF # 创建 systemd 服务(自动启动) sudo bash -c "cat > /etc/systemd/system/frps.service <<'SVC' [Unit] Description=frp server After=network-online.target Wants=network-online.target [Service] Type=simple User=$(whoami) Restart=on-failure RestartSec=5s ExecStart=${FRP_DIR}/frps -c ${FRP_DIR}/frps.toml [Install] WantedBy=multi-user.target SVC" # 启动服务 sudo systemctl daemon-reload sudo systemctl enable frps sudo systemctl start frps echo "" echo "✓ frps 服务已启动" echo "检查状态: sudo systemctl status frps" echo "" echo "=========================================" echo "⚠️ 请将上面生成的 Token 复制保存!" echo "客户端配置时需要使用相同的 Token" echo "=========================================" 1.3 验证服务状态 # 检查服务状态 sudo systemctl status frps # 实时查看日志 sudo journalctl -u frps -f # 确认端口监听 sudo ss -tlnp | grep 7000 # 应该看到类似输出: # LISTEN 0 128 0.0.0.0:7000 0.0.0.0:* users:(("frps",pid=xxxx,fd=x)) 2. 内网客户端配置(frpc) 2.1 下载 frp # SSH 登录到内网服务器 ssh your_user@INTERNAL_SERVER_IP # 下载 frp(版本应与服务端一致) wget https://github.com/fatedier/frp/releases/download/v0.65.0/frp_0.65.0_linux_amd64.tar.gz # 解压 tar -xzf frp_0.65.0_linux_amd64.tar.gz cd frp_0.65.0_linux_amd64 2.2 一键部署脚本 #!/bin/bash # 文件名: deploy_frpc.sh # 在内网服务器上执行 set -e # ⚠️ 重要:请替换为云服务器生成的 Token! read -p "请输入云服务器生成的 Token: " TOKEN if [ -z "$TOKEN" ]; then echo "错误: Token 不能为空!" exit 1 fi # ⚠️ 重要:请替换为你的云服务器公网 IP read -p "请输入云服务器的公网 IP: " SERVER_ADDR if [ -z "$SERVER_ADDR" ]; then echo "错误: 服务器地址不能为空!" exit 1 fi FRP_VERSION="0.65.0" FRP_DIR="$HOME/frp_${FRP_VERSION}_linux_amd64" # 下载并安装 frp cd ~ wget https://github.com/fatedier/frp/releases/download/v${FRP_VERSION}/frp_${FRP_VERSION}_linux_amd64.tar.gz tar -xzf frp_${FRP_VERSION}_linux_amd64.tar.gz cd ${FRP_DIR} # 创建客户端配置 cat > frpc.toml <<EOF # frpc 客户端配置 serverAddr = "${SERVER_ADDR}" serverPort = 7000 # Token 认证(必须与服务端一致) auth.method = "token" auth.token = "${TOKEN}" # 日志配置 log.to = "./frpc.log" log.level = "info" log.maxDays = 7 # 连接池配置 transport.poolCount = 1 # SSH 端口转发(本地22 -> 远程8606) [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = 8606 # Web 服务端口转发(根据需要调整) [[proxies]] name = "web_8502" type = "tcp" localIP = "127.0.0.1" localPort = 8502 remotePort = 8502 # 如果有多个服务,继续添加 # [[proxies]] # name = "web_8500" # type = "tcp" # localIP = "127.0.0.1" # localPort = 8500 # remotePort = 8500 EOF # 创建 systemd 服务 sudo bash -c "cat > /etc/systemd/system/frpc.service <<SVC [Unit] Description=frp client After=network-online.target Wants=network-online.target [Service] Type=simple User=${USER} Restart=on-failure RestartSec=5s ExecStart=${FRP_DIR}/frpc -c ${FRP_DIR}/frpc.toml [Install] WantedBy=multi-user.target SVC" # 启动服务 sudo systemctl daemon-reload sudo systemctl enable frpc sudo systemctl start frpc echo "✓ frpc 服务已启动" echo "检查状态: sudo systemctl status frpc" 2.3 验证连接状态 # 检查 frpc 服务 systemctl status frpc # 查看日志(重要:确认是否连接成功) journalctl -u frpc -n 50 # ✅ 成功的日志应该显示: # [I] [client/service.go:xxx] login to server success, get run id [xxxxxxxx] # [I] [proxy/proxy_manager.go:xxx] proxy added: [ssh web_8502] # [I] [client/control.go:xxx] [ssh] start proxy success # ❌ 如果看到以下错误,说明有问题: # "i/o timeout" - 网络连接问题,检查安全组配置 # "authentication failed" 或 "token doesn't match" - Token 不一致 3. HTTP 密码保护(推荐) 问题:为什么需要额外的密码保护? 即使配置了 frp,只要知道 http://YOUR_SERVER_IP:8502 这个地址,任何人都能访问你的服务。 解决方案:在云服务器上用 Nginx 添加 HTTP Basic Auth。 为什么使用 Nginx 而不是 frp 自带的 HTTP 认证? 对于 Streamlit、Jupyter 等需要 WebSocket 的应用: ❌ frp 的 type = "http" + httpUser/httpPassword 不完全支持 WebSocket ✅ 保持 frp 使用 type = "tcp",用 Nginx 添加认证,完美支持 WebSocket 方案选择 方案A(推荐):单服务,无需修改应用配置 访问地址:http://YOUR_SERVER_IP/ 应用端无需任何特殊配置 方案B:多服务,需要配置应用的 baseUrlPath 访问地址:http://YOUR_SERVER_IP/app1/、/app2/ 等 需要修改 Streamlit 等应用的启动参数 方案A:单服务版(一键脚本) #!/bin/bash # 文件名: setup_nginx_auth.sh # 在云服务器上执行 set -e # 安装 Nginx 和密码工具 sudo apt update sudo apt install -y nginx apache2-utils # 创建用户和密码(请修改用户名和密码) USERNAME="your_username" echo "请输入密码:" sudo htpasswd -c /etc/nginx/.htpasswd ${USERNAME} # 配置 Nginx 反向代理 + Basic Auth sudo tee /etc/nginx/sites-available/frp-auth <<'EOF' server { listen 80 default_server; server_name _; # 根路径代理到应用(如 Streamlit) location / { auth_basic "Restricted Access - Please Login"; auth_basic_user_file /etc/nginx/.htpasswd; # 反向代理到 frp 映射的端口 proxy_pass http://127.0.0.1:8502; proxy_http_version 1.1; # WebSocket 支持(Streamlit/Jupyter 必需) proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 其他必要的 headers proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 超时设置(适应长连接) proxy_read_timeout 86400; } } EOF # 启用配置 sudo ln -sf /etc/nginx/sites-available/frp-auth /etc/nginx/sites-enabled/ sudo rm -f /etc/nginx/sites-enabled/default # 删除默认配置 sudo nginx -t # 测试配置 sudo systemctl reload nginx sudo systemctl enable nginx echo "✓ Nginx HTTP Auth 已配置" echo "访问地址: http://YOUR_SERVER_IP/" echo "用户名: ${USERNAME}" 应用端配置(内网服务器): # Streamlit 示例:无需任何额外选项! streamlit run app.py --server.port=8502 # Jupyter 示例 jupyter notebook --ip=127.0.0.1 --port=8502 --no-browser 访问方式: http://YOUR_SERVER_IP/ # 浏览器会提示输入用户名密码 方案B:多服务版(参考) 如果需要同时运行多个应用(8502、8500、8504),可以配置子路径: # 在 Nginx 配置中添加多个 location location /app1/ { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://127.0.0.1:8502/; # ... 其他配置同上 } location /app2/ { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://127.0.0.1:8500/; # ... 其他配置同上 } 对应的应用需要配置 baseUrlPath: streamlit run app.py --server.baseUrlPath=/app1 --server.port=8502 安全增强:关闭直接端口访问 配置 Nginx 后,在云服务器安全组中: 移除 8502/8500/8504 的入站规则 只开放 80 端口(HTTP)或 443 端口(HTTPS) 这样外部只能通过 Nginx(需要密码)访问,无法绕过认证 4. 完整部署流程 graph TB subgraph SG3[客户端测试] direction LR M[步骤5:测试访问] M --> N{访问正常?} N -->|否| O[检查配置] O --> N end A[开始部署] --> SG1 --> SG2 --> SG3 subgraph SG2[客户端部署] direction LR G[步骤3:部署frpc] --> H{Token一致?} H -->|否| I[修改配置] I --> H H -->|是| J{连接成功?} J -->|否| K[排查网络] K --> J J -->|是| L[步骤4:配置Nginx] end N -->|是| P[部署完成] subgraph SG1[服务端部署] direction LR B[步骤1:配置安全组] --> C[步骤2:部署frps] C --> D{启动成功?} D -->|否| E[检查日志] E --> C D -->|是| F[服务端完成] end style A fill:#e1f5e1 style F fill:#ccf style P fill:#e1f5e1 style D fill:#ffe4e1 style H fill:#ffe4e1 style J fill:#ffe4e1 style N fill:#ffe4e1 详细步骤 步骤 1:配置云服务器安全组 在云服务商控制台,添加入站规则: TCP 7000 端口:0.0.0.0/0(frp 控制) TCP 80 端口:0.0.0.0/0(HTTP 访问) 步骤 2:部署云服务器端 # 执行 1.2 节的部署脚本 bash deploy_frps.sh # 验证服务 sudo systemctl status frps 步骤 3:部署内网客户端 # 执行 2.2 节的部署脚本 bash deploy_frpc.sh # 验证连接 journalctl -u frpc -n 20 步骤 4:配置 Nginx(可选但推荐) # 执行 3 节的 Nginx 配置脚本 bash setup_nginx_auth.sh 步骤 5:测试访问 # 测试 frp 连接 nc -zv YOUR_SERVER_IP 7000 # 浏览器访问(有密码保护) http://YOUR_SERVER_IP/ # 或直接访问端口(无密码保护,不推荐) http://YOUR_SERVER_IP:8502 # SSH 连接测试 ssh -p 8606 your_user@YOUR_SERVER_IP 5. 常见问题排查 Q1: “token doesn’t match” 认证失败 现象: [E] [client/service.go:310] token in login doesn't match token from configuration 原因:云服务器和内网服务器的 Token 不一致,或修改后未重启服务 解决步骤: # 1. 检查两边 Token 是否一致 # 云服务器: grep "auth.token" /path/to/frp/frps.toml # 内网服务器: grep "auth.token" /path/to/frp/frpc.toml # 2. 如果不一致,修改配置文件,确保 Token 完全相同 # 3. 重启两边服务(重要!) # 云服务器: sudo systemctl restart frps # 内网服务器: sudo systemctl restart frpc # 4. 验证连接成功 journalctl -u frpc -n 20 | grep "login to server success" Q2: “i/o timeout” 无法连接 原因:网络连通性问题,通常是安全组配置不正确 解决方法: # 1. 测试网络连通性 nc -zv YOUR_SERVER_IP 7000 # 2. 检查云服务器安全组 # 确保 7000 端口的入站规则源地址为 0.0.0.0/0 # 3. 检查云服务器防火墙(如果有) sudo ufw status sudo ufw allow 7000/tcp # 4. 重启 frpc sudo systemctl restart frpc Q3: Streamlit/Jupyter 连接卡住或 WebSocket 错误 原因:Nginx 配置缺少 WebSocket 支持 解决方法: 确保 Nginx 配置包含以下关键行: proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400; Q4: 配置 Nginx 后无法访问 检查清单: # 1. 确认 Nginx 服务运行 sudo systemctl status nginx # 2. 测试 Nginx 配置 sudo nginx -t # 3. 确认端口监听 sudo ss -tlnp | grep :80 # 4. 检查 frp 端口是否正常 curl http://127.0.0.1:8502 # 5. 查看 Nginx 日志 sudo tail -f /var/log/nginx/error.log Q5: 服务重启后 frp 未自动启动 解决方法: # 确保 systemd 服务已启用 sudo systemctl enable frps # 云服务器 sudo systemctl enable frpc # 内网服务器 # 检查服务状态 sudo systemctl status frps sudo systemctl status frpc 快速命令参考 # === 服务管理 === # 云服务器 sudo systemctl status/start/stop/restart frps sudo systemctl enable frps # 开机自启 # 内网服务器 sudo systemctl status/start/stop/restart frpc sudo systemctl enable frpc # === 日志查看 === # 实时日志 sudo journalctl -u frps -f # 云服务器 sudo journalctl -u frpc -f # 内网服务器 # 最近50行日志 sudo journalctl -u frps -n 50 sudo journalctl -u frpc -n 50 # === 测试命令 === # 测试 frp 控制端口 nc -zv YOUR_SERVER_IP 7000 # 测试 HTTP 访问 curl -I http://YOUR_SERVER_IP/ # 测试本地服务 curl http://127.0.0.1:8502 # SSH 连接测试 ssh -p 8606 your_user@YOUR_SERVER_IP # === Nginx 管理 === sudo systemctl status/reload/restart nginx sudo nginx -t # 测试配置 sudo tail -f /var/log/nginx/access.log sudo tail -f /var/log/nginx/error.log 总结与最佳实践 安全建议 Token 管理:使用强随机 Token,妥善保存,定期更换 多层防护:Token 认证 + HTTP Basic Auth + 安全组限制 最小权限:只开放必要的端口,关闭不需要的服务 日志监控:定期检查 frp 和 Nginx 日志,发现异常访问 HTTPS 升级:生产环境建议配置 SSL 证书(Let’s Encrypt 免费) 性能优化 连接池配置:根据并发需求调整 transport.poolCount 心跳超时:稳定网络可适当增加 heartbeatTimeout 日志轮转:配置 log.maxDays 避免日志文件过大 故障恢复 自动重启:systemd 配置已包含 Restart=on-failure 监控告警:可配合监控工具(如 Prometheus)监控服务状态 备份配置:定期备份 frps.toml 和 frpc.toml 参考资源 frp 官方文档:https://gofrp.org/zh-cn/docs/ frp GitHub 仓库:https://github.com/fatedier/frp Nginx 官方文档:https://nginx.org/en/docs/ HTTP Basic Auth:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Authentication 本文更新时间:2025-10-22 作者:Xufan Gao
Techniques
· 2025-11-02
让 Claude Code 控制浏览器:Playwright MCP 完全配置指南
让 Claude Code 控制浏览器:Playwright MCP 完全配置指南 引言 想让 AI 直接帮你操作浏览器吗?Model Context Protocol (MCP) 让这一切成为现实。通过 MCP 服务器,Claude Code 可以像人类一样浏览网页、填写表单、截图、抓取数据,甚至生成自动化测试代码。 Playwright MCP 是微软官方推出的浏览器自动化 MCP 服务器,它采用基于可访问性树的创新方法,无需视觉模型即可让 LLM 理解网页结构。这意味着更快的响应速度、更低的资源消耗,以及更精准的页面交互。 本文将手把手教你如何在 Claude Code 中配置 Playwright MCP,让 AI 成为你的浏览器自动化助手。 什么是 MCP? Model Context Protocol (MCP) 是 Anthropic 推出的开放协议,用于连接 AI 应用与外部数据源和工具。通过 MCP,LLM 可以: 访问文件系统、数据库、API 操作浏览器、执行代码 与 GitHub、Slack 等第三方服务集成 MCP 的设计理念是标准化 AI 与工具的连接方式,就像 USB 协议统一了设备连接标准一样。开发者只需实现一次 MCP 服务器,就能在所有支持 MCP 的 AI 应用中使用。 Playwright MCP 是 MCP 生态中最受欢迎的浏览器自动化工具之一,由微软官方维护,已被数千个项目使用。 实际应用场景 安装 Playwright MCP 后,你可以让 Claude Code 帮你: Web 开发调试 “访问我的本地开发服务器 localhost:3000 并截图” “检查页面控制台是否有错误信息” “点击登录按钮,填写测试账号并提交表单” 数据抓取 “访问这个产品页面,提取所有商品标题和价格” “抓取这个表格的数据并整理成 CSV 格式” 自动化测试 “生成这个登录流程的 Playwright 测试代码” “验证这个页面在不同屏幕尺寸下的布局” 内容监控 “每天检查这个网站的首页内容变化” “监控竞品的价格更新” MCP 服务器对比 Claude Code 支持两种主流浏览器自动化 MCP 服务器: Playwright MCP(推荐):微软官方出品,支持多浏览器(Chrome/Firefox/WebKit),无需图形界面,性能优异 Chrome DevTools MCP:基于 Chrome DevTools Protocol,适合 Chrome 专用调试场景 安装后,只需在对话中提及浏览器操作(如”访问这个网址并截图”),Claude Code 会自动调用相应的 MCP 工具完成任务。 完整安装步骤(Ubuntu/Debian) 方案一:Playwright MCP(推荐) # 1. 添加到 Claude Code(无头模式) claude mcp add -s user playwright -- npx @playwright/mcp@latest --headless # 2. 安装 Playwright 浏览器 npx playwright install chromium # 3. 安装系统依赖 sudo apt-get update sudo apt-get install -y \ libnss3 libnspr4 libdbus-1-3 \ libatk1.0-0 libatk-bridge2.0-0 \ libcups2 libdrm2 libxkbcommon0 \ libxcomposite1 libxdamage1 libxfixes3 \ libxrandr2 libgbm1 libpango-1.0-0 \ libcairo2 libasound2 # 4. 验证安装 npx playwright --version # 5. 完成!现在可以在 Claude Code 中使用浏览器功能 优点: 无需图形界面(X Server) 支持多浏览器(Chrome、Firefox、WebKit) 系统依赖少 开箱即用 方案二:Chrome DevTools MCP(备选) # 1. 添加到 Claude Code claude mcp add chrome-devtools npx chrome-devtools-mcp@latest # 2. 安装 Chrome 浏览器 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo apt install ./google-chrome-stable_current_amd64.deb # 3. 安装 Puppeteer 系统依赖 sudo apt-get update sudo apt-get install -y \ ca-certificates fonts-liberation \ libappindicator3-1 libasound2 \ libatk-bridge2.0-0 libatk1.0-0 \ libcairo2 libcups2 libdbus-1-3 \ libgbm1 libglib2.0-0 libgtk-3-0 \ libnspr4 libnss3 libpango-1.0-0 \ libx11-6 libxcomposite1 libxdamage1 \ libxext6 libxfixes3 libxrandr2 \ libxrender1 libxss1 libxtst6 \ xdg-utils wget # 4. 如果无图形界面,安装 xvfb(虚拟显示) sudo apt-get install -y xvfb # 5. 验证安装 google-chrome --version # 6. 完成! 安装完成后,你就可以开始让 AI 帮你自动化浏览器操作了! 注意: 需要更多系统依赖 在无图形界面的服务器上需要 xvfb 仅支持 Chrome/Chromium 使用方法 安装完成后,直接在对话中提及浏览器操作即可,例如: 你:请访问 http://localhost:8504 并截图 Claude:好的,我来访问这个地址... [自动调用 mcp__playwright__browser_navigate] 你:查看页面上的错误信息 Claude:我来检查控制台日志... [自动调用 mcp__playwright__browser_console_messages] 你:点击"Performance Analysis"标签 Claude:我来点击这个标签... [自动调用 mcp__playwright__browser_click] Claude Code 会自动选择合适的 MCP 工具执行操作。 常见问题 1. Playwright 找不到浏览器 # 重新安装浏览器 npx playwright install --force chromium # 或指定浏览器路径 export PLAYWRIGHT_BROWSERS_PATH=/path/to/browsers npx playwright install 2. Chrome DevTools 报错:”Missing X server” 这是因为服务器没有图形界面。解决方案: # 方案 A:安装 xvfb(虚拟显示) sudo apt-get install -y xvfb # 方案 B:使用 Playwright(推荐) # Playwright 默认无头模式,无需图形界面 claude mcp add -s user playwright -- npx @playwright/mcp@latest --headless 3. 权限错误 # 使用 sudo 安装系统依赖 sudo npx playwright install-deps # 或修改 npm 全局目录权限 mkdir ~/.npm-global npm config set prefix '~/.npm-global' echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc source ~/.bashrc 4. 检查 MCP 是否安装成功 # 查看已安装的 MCP 服务器 claude mcp list # 测试 Playwright npx playwright --version # 测试 Chrome google-chrome --version 方案对比 特性 Playwright MCP Chrome DevTools MCP 安装难度 非常简单 中等 无头模式 默认支持 需要配置 多浏览器 Chrome, Firefox, WebKit 仅 Chrome 系统依赖 少 多 需要 X Server 不需要 需要(或 xvfb) 性能 快 中等 推荐场景 通用自动化、测试 Chrome 专用调试 推荐:优先使用 Playwright MCP,特别是在无图形界面的服务器上。 参考资源 Playwright MCP GitHub 仓库:https://github.com/microsoft/playwright-mcp Playwright 官方文档:https://playwright.dev Model Context Protocol 规范:https://modelcontextprotocol.io Claude Code MCP 文档:https://docs.claude.com/en/docs/claude-code Chrome DevTools Protocol:https://chromedevtools.github.io/devtools-protocol MCP Hub(发现更多 MCP 服务器):https://mcphub.com 另外再推荐个小工具 cc相关的工具太多了,肯定学不完,随缘了。
Techniques
· 2025-11-02
【笔记整理|2024-07】力场与分子建模:从Martini 3粗粒化到OPLS-AA全原子力场
【笔记整理|2024-07】力场与分子建模:从Martini 3粗粒化到OPLS-AA全原子力场 引言 分子力场是分子动力学模拟的基石,不同的力场适用于不同的研究目的和应用场景。本文整理了从技术讨论中提取的关于Martini 3粗粒化力场、OPLS-AA全原子力场以及其他重要力场系统的关键知识和实用技巧,涵盖力场选择、参数化策略和应用实践。 Martini 3粗粒化力场 Martini 3设计理念 Martini 3是目前最先进的粗粒化力场之一,其设计理念基于系统性的参数化策略: The OPLS-AA force field has followed a consistent philosophy throughout the course of its development. Nonbonded parameters are optimized to reproduce experimental liquid phase properties, and torsional parameters are fit to available experimental or quantum chemical data. The Martini FF has been parametrized towards dielectric screening constant of 15, part of the electrostatic interactions have been included in the LJ parameters, therefore changing the screening constant would mean that you would also have to parametrize the LJ interactions. In short we would not advice fiddling with the screening. Martini 3珠子类型系统 珠子类型示例: The magnesium ion is represented by one TQ3p bead with a charge of +1 Martini 3参数化资源 Martini 3提供了丰富的参数化资源和数据库: https://github.com/Martini-Force-Field-Initiative/M3-Sterol-Parameters/blob/main/martini_v3.0_sterols_v1.0.itp https://github.com/Martini-Force-Field-Initiative/M3-Lipid-Parameters https://github.com/ricalessandri/Martini3-small-molecules/tree/main Martini 3蛋白质-配体结合模拟 Martini 3在蛋白质-配体结合模拟方面具有独特优势: CHAPTER 1 A PRACTICAL INTRODUCTION TO MARTINI 3 AND ITS APPLICATION TO PROTEIN-LIGAND BINDING SIMULATIONS Martini 3介电常数 Martini 3的介电常数设置是其重要特征: There is actually an option in the mdp file to change the dielectric OPLS-AA全原子力场 OPLS-AA设计哲学 OPLS-AA力场具有明确的参数化哲学和一致性原则: The OPLS-AA force field has followed a consistent philosophy throughout the course of its development. Nonbonded parameters are optimized to reproduce experimental liquid phase properties, and torsional parameters are fit to available experimental or quantum chemical data. OPLS-AA参数转换 OPLS-AA力场的参数在转换为GROMACS格式时需要注意一些细节: https://github.com/leelasd/OPLS-AAM_for_Gromacs/tree/master parmed CharmmParameterSet, all bonds,angles,dihedrals have two copied, where atom names are reversed, so we don’t need to sort? PolyParGen聚合物参数化 PolyParGen为聚合物和大分子提供OPLS-AA和Amber力场参数: PolyParGen provides OPLS-AA and Amber force field parameters for polymers or large molecules. In the case that PolyParGen generates OPLS-AA parameters… 分子力场参数化 参数化策略 不同力场采用不同的参数化策略,需要根据研究需求选择: We can use mols2grid to display and scroll through the cluster samples 力场参数文件格式 力场参数文件的格式和结构对于正确使用力场至关重要: vmd modeling top_opls_aam.inp problematic IC: VAL, ILE, MET, CYS, PRO…. vdwGeometricSigma yes 排除约束设置 合理的排除约束设置是力场配置的重要部分: For the [ exclusions ] section: For the [ constraints ] section: Extra exclusions within a molecule can be added manually in a [ exclusions ] section. Each line should start with one atom index, followed by one or more atom indices. All non-bonded interactions between the first atom and the other atoms will be excluded. 特殊相互作用与拓扑处理 质子海绵效应 质子海绵效应在分子模拟中是一个特殊的现象: proton sponge effect 受限弯曲势能 受限弯曲势能用于模拟特殊的分子结构: https://manual.gromacs.org/documentation/current/reference-manual/functions/bonded-interactions.html#restricted-bending-potential 虚拟位点 虚拟位点是分子力场中用于简化计算的重要技术: https://manual.gromacs.org/current/reference-manual/functions/interaction-methods.html#virtualsites 力场兼容性与转换 不同力场的兼容性 不同力场之间的兼容性是混合模拟中的关键问题: WARNING 3 [file ../../mdps_cg_78.4_mem/em.mdp]: ERROR 1 [file ../../mdps_cg_78.4_mem/nvt_neutral.mdp]: 力场参数验证 力场参数的验证确保模拟的可靠性: WARNING 4 [file system.top, line 13]: 力场组合使用 在某些情况下,需要组合使用不同的力场: 36 1 makes vmd output “psfgen) Created by CHARMM version 36 1” not useful in FEbuilder 分子建模工具与技术 SMARTS模式匹配 SMARTS模式匹配是分子结构识别的重要工具: SMARTS matching emm, cannot ensure won’t cause the same problem as rdkit 分子体积计算 分子体积计算是分子表征的重要参数: https://www.rdkit.org/docs/source/rdkit.Chem.AllChem.html#rdkit.Chem.AllChem.ComputeMolVolume from rdkit.Chem import rdMolDescriptors 分子表示与立体化学 立体化学的正确表示对分子模拟至关重要: Stereogenic centers belonging to an AND n group (e.g. AND1) represents a mixture of two enantiomers: the structure as drawn AND the epimer in which the stereogenic centers have the opposite configuration. (Note, that it is not a racemic mixture, but a mixture of the enantiomers of any ratio. Of course, a 1:1 mixture (racemic mixture) is included in this sense.) 特殊分子系统 膜蛋白与去垢剂 膜蛋白的模拟需要特殊的去垢剂处理: In addition, many proteins (especially membrane proteins) would aggregate if the SDS were simply washed out, this could lead to loss of activity. Non-ionic detergents like Triton solubilise proteins gently, often maintaining its activity. 荧光染料特性 荧光染料在生物物理研究中具有广泛应用: FITC reacts with a primary amine on the protein to form a covalent amide bond. Hoechst dyes are cell membrane-permeant, minor groove-binding blue fluorescent DNA stains. These dyes are widely used in cell cycle and apoptosis studies as nuclear counterstains. 圆二色谱计算 圆二色谱(CD)是研究蛋白质二级结构的重要技术: The DichroCalc web server [38] was used to calculate CD spectra from molecular 自由能计算与力场应用 软核相互作用 自由能计算中的软核相互作用避免奇点问题: https://manual.gromacs.org/current/reference-manual/functions/free-energy-interactions.html#soft-core-interactions-beutler-et-al 自由能计算工具 专业的自由能计算工具提高了模拟效率: https://github.com/delphi001/DelphiPka https://rowansci.com/tools/pka https://github.com/mms-fcul/PypKa https://valdes-tresanco-ms.github.io/gmx_MMPBSA/v1.5.5/command-line/ 自由能计算标准流程 标准化的自由能计算流程确保结果的可比性: https://alchemistry.org/wiki/Exponential_Averaging 力场发展与前沿趋势 新兴力场系统 力场技术不断发展,出现了许多新兴的力场系统: https://www.bohrium.com/notebooks/38543442597 开源力场项目 开源力场项目促进了力场技术的普及和发展: https://github.com/OpenFreeEnergy/openfe-benchmarks https://github.com/drazen-petrov/SMArt https://github.com/OpenFreeEnergy/konnektor 商业力场软件 商业力场软件提供了专业的技术支持和服务: NVIDIA NIM for Boltz-2 https://qsimulate.com/documentation/fep_tutorial/fep_tutorial.html 力场验证与质量控制 力场验证标准 力场验证是确保模拟结果可靠性的关键步骤: math font still use normal 力场参数数据库 力场参数数据库为研究人员提供了丰富的资源: https://www.wiredchemist.com/chemistry/data/metallic-radii 力场性能评估 力场性能评估帮助选择最适合的力场: https://www.r-ccs.riken.jp/labs/cbrt/tutorial/remd-tutorials/tutorial-2-1/ https://manual.gromacs.org/current/reference-manual/analysis/correlation-function.html 总结与最佳实践 力场选择:根据研究目的选择合适的力场系统,Martini 3适合大系统长时间尺度,OPLS-AA适合高精度全原子模拟 参数化策略:理解不同力场的参数化哲学,确保参数的一致性和可靠性 兼容性考虑:在混合力场模拟中,充分考虑不同力场之间的兼容性问题 验证流程:建立完善的力场验证流程,确保模拟结果的可靠性 工具使用:熟练使用各种力场建模和分析工具,提高研究效率 前沿跟踪:关注力场技术的最新发展,及时更新知识体系 质量控制:建立严格的质量控制标准,确保研究成果的可重复性 社区参与:积极参与开源力场项目,促进力场技术的发展 通过这些力场知识和建模技巧的掌握,可以显著提高分子动力学模拟的质量和效率。 参考资源 Martini 3固醇参数 Martini 3脂质参数 Martini 3小分子参数 OPLS-AA for GROMACS gmx_MMPBSA手册 DelphiPKa PypKa RowanSci pKa工具 自由能计算指数平均方法 限制性弯曲势能文档
Techniques
· 2025-10-11
【笔记整理|2024-07】计算化学工具集锦:RDKit、VMD、PyMOL实战技巧
【笔记整理|2024-07】计算化学工具集锦:RDKit、VMD、PyMOL实战技巧 引言 计算化学研究离不开专业的软件工具,这些工具为分子建模、数据分析和可视化提供了强大的支持。本文整理了从技术讨论中提取的关于RDKit、VMD和PyMOL等重要计算化学工具的使用技巧和最佳实践,涵盖从分子描述符计算到高级可视化的各个方面。 RDKit分子信息学工具 分子指纹生成 分子指纹是化学信息学中用于表征分子结构的重要工具,RDKit提供了多种指纹生成方法: You can use DrawMorganBit() as described in the RDKit-Blog Morgan指纹生成器教程: https://greglandrum.github.io/rdkit-blog/posts/2023-01-18-fingerprint-generator-tutorial.html 分子描述符计算 RDKit提供了丰富的分子描述符计算功能,包括分子体积等几何性质: https://www.rdkit.org/docs/source/rdkit.Chem.AllChem.html#rdkit.Chem.AllChem.ComputeMolVolume from rdkit.Chem import rdMolDescriptors 分子绘制与可视化 RDKit不仅提供计算功能,还支持分子的可视化绘制: from rdkit.Chem import Draw, AllChem 目前rdkit.Chem.Draw.MolsToGridImage函数没有直接设置图例字体大小的选项 VMD分子动力学可视化 分子拓扑构建 VMD的psfgen插件是构建分子拓扑结构的强大工具,但在使用过程中需要注意一些常见问题: vmd modeling is stupid: residue 5 is a normal residue that contains BOND C +N, while residue 6 does not include N (but NC) atom. so vmd creates a bond between residue 5 C and the last atom (PHE HE2B)??? how to fix? Both angles and dihedrals are generated automatically unless “auto none” is added CG工具集 VMD提供了粗粒化建模工具集: http://www.ks.uiuc.edu/Research/vmd/plugins/cgtools/ 分子操作命令 VMD提供了丰富的分子操作命令,包括删除和重命名对象: chimerax remove molecule: close #3 pymol rename object: set_name old_name, new_name PyMOL分子可视化与结构分析 蛋白质轨迹对齐 在分析分子动力学轨迹时,通常需要将蛋白质结构对齐到参考构象: To align a protein trajectory to its first frame in PyMOL, use the intra_fit command. RMSD计算与结构比较 PyMOL提供了强大的结构比较功能: rmsd (#1/B & backbone) to (#2/B & backbone) RMSD计算命令文档: https://www.cgl.ucsf.edu/chimerax/docs/user/commands/rmsd.html 结构显示与投影 PyMOL支持多种结构显示模式和投影设置: set orthoscopic, on https://pymolwiki.org/index.php/Clip 二级结构分析 二级结构分析是蛋白质结构研究的重要内容: Normally VMD uses the program STRIDE in order to determine the secondary structure of molecules. STRIDE程序文档: https://github.com/josch/stride/blob/master/doc/stride.doc The “bulge” of the π-helix can be clearly seen, and was created as the result of a single amino acid that has been inserted into an α-helix. PDB code 3QHB. 分子相互作用分析工具 RMSF计算 RMSF(Root Mean Square Fluctuation)是分析蛋白质柔性重要指标: https://www.researchgate.net/post/How-can-I-calculate-the-RMSF-of-a-protein-in-VMD 距离计算工具 分子间距离计算对于分析相互作用模式非常重要: https://www.researchgate.net/post/How_can_I_calculate_distance_between_two_C-alpha_atoms_in_Gromacs 数据处理与可视化库 数据分析与绘图 Python中的数据处理和可视化工具为计算化学研究提供了强大支持: def regression_plot(df, label1, label2): https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.plot.html 色彩映射设置 在数据可视化中,色彩映射的选择对于数据的表达非常重要: In the context of seaborn.diverging_palette(), h_neg and h_pos refer to the anchor hues that define the endpoints of the color spectrum for the diverging palette. These hues are specified in the HUSL (Hue, Saturation, Lightness) color space, where hue is an angle on the color wheel ranging from 0 to 360 degrees. Matplotlib高级功能 Matplotlib提供了丰富的可视化定制功能: In Matplotlib, the axes can be easily hidden by calling the set_visible() method on the axes object and setting it to False. This can be done either by using the axes object itself or by looping through the list of axes in a figure. 雨云图(Raincloud Plots) 雨云图是一种结合了箱线图、散点图和密度图的可视化方法: https://medium.com/@alexbelengeanu/getting-started-with-raincloud-plots-in-python-2ea5c2d01c11 深度学习与分子建模 分子相互作用指纹 LUNA工具包提供了将蛋白质-配体相互作用编码为指纹的方法: Therefore, we propose LUNA, a Python 3 toolkit that calculates and encodes protein–ligand interactions into new hashed fingerprints inspired by Extended Connectivity FingerPrint (ECFP): EIFP (Extended Interaction FingerPrint), FIFP (Functional Interaction FingerPrint), and Hybrid Interaction FingerPrint (HIFP). LUNA also provides visual strategies to make the fingerprints interpretable. DeepChem化学信息学 DeepChem是一个专注于化学和药物发现的深度学习库: import deepchem as dc 拓扑指纹生成 RDKit的拓扑指纹生成器为分子结构表征提供了更多选择: https://rdkit.org/docs/source/rdkit.Chem.rdFingerprintGenerator.html#rdkit.Chem.rdFingerprintGenerator.GetTopologicalTorsionGenerator 分子网格显示工具 Mols2Grid交互式显示 Mols2Grid提供了一个交互式的分子网格显示工具: We can use mols2grid to display and scroll through the cluster samples 分子网格显示优化 分子网格显示的优化对于大规模化合物库的浏览非常重要: mols2grid doesn’t require parallel processing as it’s already optimized internally 文件操作与数据处理 Zip文件处理 在处理大量数据时,文件压缩和解压是必要的技能: Working with Zip Files 文件压缩操作指南: https://docs.hostdime.com/hd/command-line/how-to-tar-untar-and-zip-files Git版本控制 版本控制对于科研项目的管理至关重要: git config advice.addIgnoredFile false git config –global user.name “gxf1212” 包管理与环境配置 合理的包管理和环境配置是科学计算的基础: conda install conda-forge::libmamba pip install -e .[dev] 统计分析与误差评估 误差分析指标 在科学计算中,正确理解和使用误差指标非常重要: “平均无符号误差”(MUE)通常是指平均绝对误差(Mean Absolute Error, MAE),它衡量了预测值与真实值之间绝对差值的平均大小 优化性能分析 性能分析是优化计算效率的关键: Optimal pipeline for huge data: fast_histogram + memory mapping fast_histogram doesn’t require parallel processing as it’s already optimized internally 总结与最佳实践 工具选择:根据具体研究需求选择合适的计算化学工具,RDKit适合化学信息学,VMD适合可视化,PyMOL适合结构分析 性能优化:合理使用并行计算和内存映射技术,提高大规模数据处理效率 可视化:掌握多种可视化方法,从基本的分子显示到高级的数据图表 版本控制:建立良好的版本控制习惯,确保研究过程的可重现性 环境管理:使用conda等工具管理科学计算环境,确保依赖包的兼容性 通过这些工具和技巧的有效组合,可以显著提高计算化学研究的效率和质量。 参考资源 RDKit博客 - Morgan指纹教程 PyMOL RMSD计算文档 VMD CG工具集 STRIDE二级结构分析程序 雨云图Python教程 LUNA分子相互作用指纹工具包 文件压缩操作指南
Techniques
· 2025-10-11
【笔记整理|2024-07】Python开发环境构建与性能优化:从编码规范到科学计算
【笔记整理|2024-07】Python开发环境构建与性能优化:从编码规范到科学计算 引言 Python作为科学计算和数据科学的主要编程语言,其开发环境的配置和性能优化直接影响研究效率。本文整理了从技术讨论中提取的Python开发环境构建、性能优化和科学计算的实用技巧,涵盖从编码规范到高级性能优化的各个方面。 Python编码最佳实践 属性访问与动态操作 Python提供了灵活的属性访问和动态操作机制: 在Python中,如果你想要根据传递的变量动态地设置对象的属性值,可以使用setattr函数。 In Python, the getattr method is called when you try to access an attribute that does not exist, but it’s not a standard way to access attributes. Instead, you typically access attributes using the dot notation (e.g., object.attribute). 迭代器优化 在Python中,前置和后置增量操作的性能差异值得注意: To be accurate: ++i can sometimes be faster than i++ and is never slower. For fundamental data types, the compiler will very likely fix your mistake and optimise away any unneeded copying. For iterators this is more difficult and for user-defined types it may very well be impossible. 排序算法与数据结构 Python内置的排序算法和数据结构特性: 在Python 中,内置的 sorted() 函数使用的是双轴快排算法(timsort)来对序列进行排序。 这种算法的时间复杂度在最坏情况下是O(n * log n),平均情况下是O(n * log n) n * log n + a * log n ≈ n * log n < n * a log2 or ln? 哈希表与集合操作 理解Python中集合和字典的内部实现有助于性能优化: 是的,集合和字典在Python中都是通过哈希表实现的。对于集合和字典的元素或键的查找,时间复杂度通常是O(1),这是因为哈希表使得元素的位置可以快速定位。 Python性能分析 代码性能分析工具 Python提供了多种性能分析工具来识别性能瓶颈: 在Python中,你可以使用cProfile模块来分析每个函数的执行时间123。以下是一个示例: 性能分析输出示例: update_results 2 96579 66 实际性能对比 实际测试显示不同运行环境下的性能差异: pycharm profile says 71s,simply debug 56s, cmd just 31s other causes, fit: ~8s; concat: 6s process_dict 11.6s, including the two? 数据处理与优化策略 Pandas数据处理 Pandas是Python数据分析的核心库,掌握其高级功能非常重要: df = df_input.copy(deep=True) # Use pandas’ built-in copy method 大规模数据优化 处理大规模数据时,性能优化尤为重要: Optimal pipeline for huge data: fast_histogram + memory mapping fast_histogram doesn’t require parallel processing as it’s already optimized internally 字符串处理 字符串处理在数据分析中经常是性能瓶颈: transform the code into a clean, efficient, and maintainable analysis framework. 科学计算环境配置 包管理工具 合理的包管理策略可以避免依赖冲突: pip install -e .[dev] Conda环境管理 Conda是科学计算环境管理的首选工具: conda install conda-forge::libmamba 要查看pip的缓存路径,可以使用pip cache dir命令。在命令行或终端中输入该命令,pip会显示其缓存的目录。 环境共享 在多用户环境中共享conda环境可以提高效率: 看起来你想将用户 xucx 的 boltz2 Conda 环境共享给其他用户,让大家都能方便地通过 conda activate boltz2 来使用。最直接且对原用户影响较小的方式是创建符号链接。 Python科学计算生态 科学计算库 Python拥有丰富的科学计算库生态系统: import deepchem as dc 数据可视化 数据可视化是科学计算的重要组成部分: In Matplotlib, the axes can be easily hidden by calling the set_visible() method on the axes object and setting it to False. This can be done either by using the axes object itself or by looping through the list of axes in a figure. 色彩映射与数据表达 合适的色彩映射可以增强数据的可读性: In the context of seaborn.diverging_palette(), h_neg and h_pos refer to the anchor hues that define the endpoints of the color spectrum for the diverging palette. These hues are specified in the HUSL (Hue, Saturation, Lightness) color space, where hue is an angle on the color wheel ranging from 0 to 360 degrees. 高级可视化技术 高级可视化技术可以更好地展示复杂数据: https://medium.com/@alexbelengeanu/getting-started-with-raincloud-plots-in-python-2ea5c2d01c11 开发工具与环境配置 代码编辑器配置 合适的代码编辑器配置可以提高开发效率: 打开VSCode,并在左侧的文件资源管理器中选择你要检索字符串的项目文件夹。 2. 使用快捷键Ctrl+Shift+F,或者点击顶部菜单栏中的”查找” -> “查找”来打开查找面板。 3. 在查找面板的文本输入框中输入你要搜索的字符串。 你可以使用普通的文本字符串进行搜索,也可以使用正则表达式进行更高级的搜索。 PyCharm 本身是一个代码编辑器(IDE),而不是一个网页浏览器。所以它不能像 Chrome 或 Edge 那樣直接”打开”并渲染 localhost:8501 的页面内容。 前端开发与后端集成 Python在现代Web开发中也有广泛应用: 我将使用Tailwind CSS进行布局和样式设计,并采用Chart.js(用于标准图表)和Plotly.js(如果需要更复杂的图表,并确保使用Canvas/WebGL渲染)来创建可视化内容。所有图表和图示都将严格遵守无SVG和无Mermaid JS的要求,转而使用HTML/CSS、Unicode字符或Canvas来实现。 I designed a frontend to manage the analysis and figures. here’s the overview. understand it Python包管理与发布 包缓存管理 合理管理包缓存可以节省磁盘空间并提高安装速度: 要清理pip的缓存,可以使用pip cache purge命令。这将清除pip缓存的所有内容,包括已下载但未安装的包和已安装但未使用的包的缓存。如果只想清除特定包的缓存,可以使用pip cache remove 命令,将package_name替换为要清除缓存的包名。 Git与代码版本控制 版本控制是现代软件开发的标准实践: git config advice.addIgnoredFile false git config –global user.name “gxf1212” 文档生成与部署 Sphinx文档系统 Sphinx是Python项目文档生成的标准工具: How do I serve sphinx documentation locally? 用claude code写文案可能会有点过于浪费了 静态网站生成 现代文档部署通常使用静态网站生成器: 📚 Complete Workflow: Public Documentation with Private 高级编程技巧 正则表达式应用 正则表达式是文本处理的强大工具: 要查找目录名中恰好包含两个连字符的目录,需要将grep模式”锚定”以匹配整行。 代码重构与优化 代码重构是提高代码质量的重要手段: transform the code into a clean, efficient, and maintainable analysis framework. 函数设计与最佳实践 良好的函数设计是高质量代码的基础: The most straightforward and conventional method is to prefix each line of the desired comment block with the hash symbol (#). Python与AI集成 AI辅助开发 AI工具正在改变Python开发的方式: Act as an expert Python developer and help to design and create code blocks / modules as per the user specification. I asked ChatGPT about this, it says: Claude Code集成 Claude Code为Python开发提供了AI辅助: https://www.yuque.com/beihu-iq2oo/zlyf06/vlg45fk72pu9gmtk?singleDoc#%20%E3%80%8AClaude%20Code%EF%BC%9A%E8%AE%A1%E8%B4%B9%E4%B8%8E%E8%AE%A2%E9%98%85%E3%80%8B Claude Code:计费与订阅 AICodemirror,必须curl -fsSL https://download.aicodemirror.com/env_deploy/env-deploy.sh bash -s – “sk-ant-api03-JQBd6V2vGYfPrl20II1Y3mGvRoK52kP7BJKUPSh4jCSoou4Jxw7ctQ3lVFJQ36tTO10cypFIIU8MYgbQ_78E3g”之后才能用 What the Script Does: After setting the environment variables, the script finds your API key, takes the last 20 characters of it, and uses the jq command to add this snippet to a list inside the ~/.claude.json file. Specifically, it adds it to the customApiKeyResponses.approved array. must do this after sudo npm install -g @anthropic-ai/claude-code 环境配置脚本 自动化环境配置脚本可以简化开发环境搭建: (cat ~/.claude.json 2>/dev/null echo ‘null’) jq –arg key “${ANTHROPIC_API_KEY: -20}” ‘(. // {}) .customApiKeyResponses.approved = (.[], $key) unique)’ > ~/.claude.json.tmp && mv ~/.claude.json.tmp ~/.claude.json 实用编程技巧 文件操作技巧 高效的文件操作是数据处理的基础: Working with Zip Files zip s.zip software-copyright/ -r 系统命令集成 Python与系统命令的集成可以扩展功能: 03:14:40 base gxf1212@gxf-pop-os file-transfer → gnome-shell –version to fix https://extensions.gnome.org/extension/1160/dash-to-panel/ 条件判断与逻辑 良好的条件判断逻辑可以提高代码的健壮性: for what it’s worth 总结与最佳实践 编码规范:遵循Python编码规范,使用合适的属性访问方式和动态操作 性能优化:熟练使用性能分析工具,理解Python内部数据结构的实现原理 环境管理:合理使用conda和pip管理Python环境,解决依赖冲突 科学计算:掌握Python科学计算生态,包括数据处理、可视化和分析工具 开发工具:配置合适的开发环境,使用现代化的编辑器和工具链 版本控制:建立良好的Git使用习惯,确保代码的可追溯性 文档生成:使用Sphinx等工具生成高质量的项目文档 AI集成:合理利用AI工具提高开发效率,但不过度依赖 通过这些Python开发技巧的掌握,可以显著提高科学计算和数据处理的效率和质量。 参考资源 雨云图Python教程 Claude Code使用指南 文件压缩操作指南 GNOME扩展修复 VS Code搜索功能文档
Techniques
· 2025-10-11
【笔记整理|2024-07】Linux系统管理与HPC集群运维:从基础命令到SLURM作业调度
【笔记整理|2024-07】Linux系统管理与HPC集群运维:从基础命令到SLURM作业调度 引言 Linux系统管理和HPC集群运维是计算科学研究的基石。无论是本地工作站还是大型计算集群,掌握Linux系统管理技能都是必不可少的。本文整理了从技术讨论中提取的Linux系统管理和HPC集群运维的关键知识和实用技巧,涵盖从基础命令到高级作业调度的各个方面。 Linux基础命令与系统管理 系统信息查看 了解系统基本信息是系统管理的第一步。 有趣的知识: usr代表Unix System Resources,而不是user! 用户与组管理 Linux系统中的用户和组管理是多用户环境下的基础操作。 要在Linux系统中查看用户组,可以使用以下命令。usermod命令是一个用于修改用户属性的强大工具,其中包括将用户添加到现有用户组的功能。 用户组管理的重要性: 操作系统具有拥有完全权限的用户。然而,由于该用户不能与登录到系统的人员共享,因此他们临时与其他用户共享部分权限。 SSH密钥管理 SSH密钥是远程管理和自动化任务的核心。 执行ssh-keygen命令生成密钥对。我们为每个人只存储一个SSH公钥。公钥可以与世界上的任何人共享(因此称为公钥)。只有您应该访问您的私钥。 虚拟内存管理 Linux系统的虚拟内存管理对于保证大规模计算任务的稳定运行至关重要。 在Linux中,当物理内存被耗尽时,会使用swap的虚拟内存(较慢)。当物理内存和虚拟内存都耗尽时就会出现程序跑不起来、启动这个进程会杀死另外一个进程的情况,以保证程序的良好运行。 包管理 不同的Linux发行版使用不同的包管理系统。面对如此多样的指令集结构,软件开发者想要为每一种架构都编译一份软件包十分困难。因此,在Linux生态中,源代码是最通用的软件分发形式。 Zlib包安装问题处理: zlib的官网打不开,apt-get install zlib也找不到软件包,貌似不在软件源里。解决方法是打开Ubuntu Software Center,搜索zlib,找到zlib1g-dev这个包,安装成功。 使用APT安装Zlib: sudo apt install zlib1g # 如果需要开发文件(头文件和静态库) sudo apt install zlib1g-dev 模块管理系统 在HPC环境中,模块管理系统是软件环境配置的关键。 module avail # 显示可以使用的模块 SLURM作业调度系统 作业提交与资源管理 SLURM是最常用的HPC作业调度系统之一,合理配置作业参数可以显著提高计算效率。 #SBATCH --exclude=node4,node5,node7,node8,node9 节点选择策略: –nodelist只能指定一个节点,但#SBATCH –exclude=node[1-16]这种范围表示法是可行的。 作业依赖与流程管理 复杂的计算流程通常需要作业之间的依赖关系管理: SLURM依赖作业提交指南: https://bioinformaticsworkbook.org/Appendix/HPC/SLURM/submitting-dependency-jobs-using-slurm.html#gsc.tab=0 作业状态监控 实时监控作业状态是集群管理的重要功能: sacct --starttime=2024-06-29 --format=JobID%10,User%20,Partition,Submit,Start,Elapsed,AllocTRES%50 -X 作业控制 作业的暂停、恢复和取消是日常管理操作: scontrol suspend jobid 用户账户管理 在SLURM集群中管理用户账户是系统管理员的职责: sacctmgr add user User=${u} Account=urgent 云计算与远程服务 AWS EC2使用 AWS EC2是常用的云计算平台,掌握基本操作非常重要,包括文件上传和下载等操作。 环境变量配置 合理配置环境变量可以简化日常操作: export TZ='Asia/Shanghai' 文件系统与数据管理 文件压缩与解压 数据压缩和归档是数据管理的必备技能。 要清理pip的缓存,可以使用以下命令: pip cache purge # 清除所有缓存 pip cache remove <package_name> # 清除特定包的缓存 pip cache dir # 查看缓存路径 参考: Zip文件操作指南 文件搜索与过滤 高效的文件搜索和过滤可以大大提高工作效率。要查找恰好包含两个连字符的目录名,需要将grep模式”锚定”以匹配整行。排除特定文件可以使用-X选项。 Git版本控制 Git是现代科研项目的标准版本控制工具。合理配置.gitignore规则可以避免提交不必要的文件。 编译与开发环境 编译系统理解 理解编译系统的工作原理有助于解决编译问题。 gcc的编译其实是四个过程的集合,分别是预处理(preprocessing)、编译(compilation)、汇编(assembly)、链接(linking),分别由cpp、cc1、as、ld这四个程序完成,gcc是它们的封装。 C++编程技巧 掌握C++编程技巧可以提高开发效率。 在C++中,字符”*“是一个指针,包含变量的值。++i有时可以比i++更快,并且永远不会更慢。对于基本数据类型,编译器很可能会修复并优化掉任何不必要的复制。对于迭代器这更困难,对于用户定义类型可能完全不可能。 Makefile编写 Makefile是自动化编译的重要工具,可以将多个C++源文件分别编译成不同的可执行文件。 LaTeX排版系统 LaTeX是科学文档排版的标准工具。 可以使用apt命令安装LaTeX: sudo apt install texlive-latex-extra sudo apt install texlive-xetex # XeLaTeX sudo apt install texlive-bibtex-extra # BibTeX支持 中文字体支持问题: 错误”LaTeX Error: File `ctexbook.cls’ not found”表示缺少CTEX包,该包是LaTeX中用于排版中文文档的文档类文件。 参考: LaTeX安装指南 系统诊断与性能优化 系统监控工具 系统监控是保证服务稳定运行的关键。 参考: VS Code缓存清理 软件安装问题解决 解决软件安装过程中的常见问题,如”No rule to make target ‘X’“通常表示文件缺失。 云原生与容器技术 虚拟化技术 虚拟化技术是现代云计算的基础。 Hypervisor(也称为虚拟机监视器或VMM)是创建和运行虚拟机(VM)的软件。 虚拟化类型: Type 1 hypervisor: 直接在主机硬件上运行以控制硬件并管理客户操作系统。例如VMware ESXi、Microsoft Hyper-V和Xen。 Linux发行版选择 选择合适的Linux发行版对于特定应用场景很重要。 netinst版本是一个小型ISO镜像,仅包含启动安装所需的文件。DVD-1版本是一个大型ISO镜像,包含桌面环境、应用程序和其他软件。 总结与最佳实践 基础命令:掌握Linux基础命令是系统管理的基础,理解命令的内部工作原理有助于问题排查 用户管理:合理配置用户和组权限,确保系统的安全性和可管理性 SSH密钥:妥善管理SSH密钥,建立安全的远程访问机制 虚拟内存:合理配置swap空间,避免因内存不足导致的程序异常 SLURM调度:熟练掌握SLURM作业调度系统,优化计算资源使用 版本控制:建立良好的Git使用习惯,确保研究过程的可追溯性 编译环境:理解编译原理,能够独立解决编译和链接问题 监控诊断:建立系统监控体系,及时发现和解决潜在问题 通过这些系统管理和集群运维技能的掌握,可以为计算科学研究提供稳定、高效的计算环境支持。 参考资源 SLURM依赖作业提交指南 文件压缩操作指南 Linux系统监控指南 SLURM环境变量文档 LaTeX在Ubuntu上安装指南
Techniques
· 2025-10-11
分子动力学聚类分析与热图可视化技术
分子动力学聚类分析与热图可视化技术 聚类分析 首先需要准备一个包含每个聚类中帧ID的 clus_result.dat 文件,格式如下(每个聚类的第一个数字是中心构象): cluster 1: 3722 3946 0 1 4 10 23 33 36 41 45 46 47 51 54 59 61 62 63 66 67 69 76 80 84 85 ...... cluster 2: 489 1886 2 3 5 8 9 11 13 14 16 17 18 19 20 21 22 24 25 27 30 31 32 34 35 37 38 39 40 42 43 44 48 49.... .... 在VMD中通过以下TCL脚本生成: # http://github.com/anjibabuIITK/CLUSTER-ANALYSIS-USING-VMD-TCL set number 9 ;# number of clusters, others are tagged 'other' set rcutoff 1.5 ;# RMSD cutoff. unit: angstrom set step_size 1 set nframes [molinfo top get numframes] set inf 0 set nf $nframes set totframes [expr $nf - 1 ] set selA [atomselect top "fragment 1 and resid 149 to 156 and backbone"] ;# select the ligand set lists [measure cluster $selA num $number cutoff $rcutoff first $inf last $totframes step $step_size distfunc rmsd weight mass] set file [open "clus_result.dat" w] for {set i 1} {$i <= [llength $lists]} {incr i} { set lst [lindex $lists [expr $i-1]] puts $file [format "cluster %d: %d" $i [llength $lst]] puts $file $lst puts $file "" } close $file # save the coordinates of centroid structures set c01 [lindex [lindex $lists 0] 0] set sel [atomselect top all frame $c01] set real_frame [expr $c01+1] $sel writegro c01_${real_frame}.gro puts [format "write the centroid of 1st cluster: frame %d" $real_frame] set c02 [lindex [lindex $lists 1] 0] set sel [atomselect top all frame $c02] set real_frame [expr $c02+1] $sel writegro c02_${real_frame}.gro puts [format "write the centroid of 2nd cluster: frame %d" $real_frame] 然后使用Python进行可视化: import matplotlib.pyplot as plt import numpy as np import os def read_vmd_clus_result(file): data = [] with open(file, 'r') as f: while f.readline().strip().startswith('cluster'): line = f.readline().strip() data.append([int(fr) for fr in line.split()]) _ = f.readline() # empty return data def get_id_with_time(data): # data: output from read_vmd_clus_result() # return: a list of tuples, (frame_id, cluster_id) # cluster_id starts from 1 id_with_time = [] for i in range(len(data)): cl = data[i] id_with_time += [(fr, i + 1) for fr in cl] id_with_time.sort(key=lambda x: x[0]) return id_with_time font_le = {'family': 'Times New Roman', 'weight': 'demibold', 'size': 16} font_la = {'family': 'Times New Roman', 'fontname': 'Times New Roman', 'weight': 'demibold', 'size': 24} font_tc = {'family': 'Times New Roman', 'fontname': 'Times New Roman', 'weight': 'demibold', 'size': 20} font_ti = {'family': 'Times New Roman', 'fontname': 'Times New Roman', 'weight': 'demibold', 'size': 28} font_hu = {'family': 'Times New Roman', 'fontname': 'Times New Roman', 'weight': 'demibold', 'size': 36} # a framework of the plot def plot_common(xlabel, ylabel, thickness=2, title=None, size=(8,6), xpad=6, ypad=0, title_pad=0, ticks_size=16, tight=False, ax_color='black'): fig, ax = plt.subplots(figsize=size) # fix the xlabel overflow problem for axis in ['top', 'bottom', 'left', 'right']: ax.spines[axis].set_linewidth(thickness) ax.tick_params(width=thickness) ax.tick_params(axis='y', colors=ax_color, labelcolor=ax_color) # plt.xticks(font='Arial', size=16, weight='bold') # plt.yticks(font='Arial', size=16, weight='bold') plt.xticks(font='Times New Roman', size=ticks_size, weight='demibold') plt.yticks(font='Times New Roman', size=ticks_size, weight='demibold') plt.xlabel(xlabel, fontdict=font_la, labelpad=xpad) plt.ylabel(ylabel, fontdict=font_la, labelpad=ypad, color=ax_color) if title is not None: plt.title(title, fontdict=font_ti, pad=title_pad) if tight: plt.tight_layout() return fig, ax def plot_clustering_id_with_time(idxs, nsperframe, biggest=10, path=None, point=False, size=(8,6), ssize=1): # plot the frame_id with cluster_id. Marking the selected centroid frame (point) with a star. # nsperframe: convert frame_id to nanosecond # biggest: biggest cluster_id shown. Other frames are tagged 'other'. plot_common(xlabel='Time (ns)', ylabel='Cluster ID', size=size) biggest = min(biggest, int(max(idxs))) plt.yticks(np.arange(biggest+1), labels=np.arange(biggest).tolist()+['Other']) x = np.arange(len(idxs))*nsperframe y = [min(i, biggest) for i in idxs] plt.scatter(x, y, s=ssize) if point: plt.scatter(point*nsperframe, idxs[point], marker='*', s=50, color='r') print("The number of clusters: {0:d}".format(len(set(idxs)))) print("The biggest cluster lasted for {0:.1f} ns ({1:.1%})".format(np.sum(idxs==1)*nsperframe, np.sum(idxs==1)/len(idxs))) print("The second cluster lasted for {0:.1f} ns ({1:.1%})".format(np.sum(idxs==2)*nsperframe, np.sum(idxs==2)/len(idxs))) print("The unclustered frames (>=no. {2:d}) occupies {0:.1f} ns or {1:.1%}".format(np.sum(idxs>=biggest)*nsperframe, np.sum(idxs>=biggest)/len(idxs), biggest)) print("The centroid of the biggest cluster is at {0:.1f} ns.".format(point*nsperframe)) if path is not None: plt.savefig(os.path.join(path,'cluster.png')) plt.show() path = 'xxxxxxxxx/clus_result.dat' data = read_vmd_clus_result(path) id_with_time = get_id_with_time(data) plot_clustering_id_with_time(np.array(id_with_time)[:, 1], 0.5, path=os.path.dirname(path), point=data[0][0], ssize=1.25) FEP单点突变热图 读取数据: ddG = read_single() # not provided here. customize yourselves. it's just a dictionary of mutation: ddG. # you must follow the format of E1A, E10A, etc. ddG = { 'E1A': -0.783225000000002, 'V2A': 0.379990000000001, 'T3A': -0.7186525, 'E4A': 2.6721, ..... } 然后进行热图绘制: import pandas as pd from matplotlib import pyplot as plt import numpy as np import copy import seaborn as sns # also requires the above plot_common def get_matrix(ddG): columns = sorted(list(set([key[:-1] for key in ddG.keys()])), key=lambda x: int(x[1:])) rows = ['A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z'] df = pd.DataFrame(index=rows, columns=columns) df.iloc[:,:] = np.NAN # process into a matrix for key, value in ddG.items(): col, row = key[:-1], key[-1] df.loc[row, col] = value return df def heatmap_single(df): # Convert all entries to numeric values, replacing non-numeric entries with NaN df = df.apply(pd.to_numeric, errors='coerce') # NOTE: you can adjust the color here. The effect may vary with your ddG data range. cmap = sns.diverging_palette(h_neg=0, h_pos=240, n=15, as_cmap=True) # Mask for NaN values mask = df.isnull() # heatmap. no text means not done. the text color is adaptive to the background color fig, ax = plot_common('Residue Position', 'Mutant', size=(8, 10), xpad=6, ypad=0, ticks_size=14, tight=False) sns.heatmap(df, cmap=cmap, center=0, annot=True, mask=mask, fmt='.2f', cbar_kws={'label': '\u0394\u0394G (kcal/mol)', 'format': '%.2f'}, linewidths=0.5, linecolor='grey', annot_kws={'fontfamily': 'Arial'}) # Update colorbar font size cbar = ax.collections[0].colorbar cbar.ax.tick_params(labelsize=14) cbar.set_label('\u0394\u0394G (kcal/mol)', fontsize=18, weight='demibold', family='Arial') plt.show() df = get_matrix(ddG) heatmap_single(copy.deepcopy(df))
Techniques
· 2025-10-08
GROMACS拓扑文件中comb-rule与非键参数详解
title: “GROMACS Defaults in Topology Files: Understanding comb-rule and nonbond_params” date: “2025-05-31” description: “详细解析 GROMACS 拓扑文件中 defaults 指令下的组合规则和非键参数。深入理解分子动力学力场参数,为模拟配置和参数优化提供完整指南。” tags: [gromacs, topology, nonbond-params, comb-rule, force-field, molecular-dynamics, parameters] thumbnail: “/assets/img/thumbnail/dsygx.png” image: “/assets/img/thumbnail/dsygx.png” — GROMACS 中 comb-rule 与 [nonbond_params] 参数解析 本文档旨在详细解释 GROMACS 拓扑文件中 [defaults] 指令下的 comb-rule(组合规则)以及 [atomtypes] 和 [nonbond_params] 部分中非键参数(特别是 Lennard-Jones 参数)的含义和解释方式。 一、[defaults] 指令详解 在 GROMACS 的拓扑文件(通常是 .top 文件或力场主 .itp 文件)中,[defaults] 指令用于设定非键相互作用的全局默认行为。 示例 [ defaults ] ; nbfunc comb-rule gen-pairs fudgeLJ fudgeQQ 1 2 no 1.0 1.0 参数解释 nbfunc (Non-bonded function type):定义非键势函数类型。 1:Lennard-Jones 势。这是绝大多数经典力场(如 AMBER, CHARMM, OPLS, Martini)使用的形式。 2:Buckingham 势。注意:根据 GROMACS 文档和社区讨论,Buckingham 势 (nbfunc = 2) 自 GROMACS 2019 版本后可能已被弃用或不再完全支持。 参考链接:https://gromacs.bioexcel.eu/t/how-use-desired-mixing-rule-in-gromacs/10409/3 comb-rule (Combination rule):定义当 [nonbond_params] 部分没有显式给出不同原子类型 i 和 j 之间的非键参数时,如何从各自的原子类型参数([atomtypes] 部分的参数)计算出交叉项参数。 gen-pairs (Generate 1-4 pairs):决定是否自动生成1-4相互作用对(即通过3个键连接的原子对)。 yes:根据成键信息自动生成,并通常与 fudgeLJ 和 fudgeQQ 联用。 no:不自动生成,1-4相互作用需要在 [pairs] 或 [pairtypes] 部分显式定义,或者由力场设计本身通过其他方式处理(如Martini)。 fudgeLJ:如果 gen-pairs = yes,此参数定义了1-4相互作用中 Lennard-Jones 部分的缩放因子。 fudgeQQ:如果 gen-pairs = yes,此参数定义了1-4相互作用中静电部分的缩放因子。 GROMACS comb-rule:对 [atomtypes] 参数的解释及交叉项的计算 comb-rule 的设置直接影响 GROMACS 如何解释 [atomtypes] 部分中的 V 和 W 列参数,以及在 [nonbond_params] 中没有显式定义一对原子类型间的非键参数时,如何计算这些交叉项参数。 https://manual.gromacs.org/current/reference-manual/topologies/parameter-files.html#non-bonded-parameters 1. [atomtypes] 中 V 和 W 参数的解释 根据 GROMACS 手册: 如果 comb-rule = 1: $V_{ii}$ 代表 $C_{6,ii} = 4 \epsilon_{ii} \sigma_{ii}^6$ (单位:kJ mol⁻¹ nm⁶) $W_{ii}$ 代表 $C_{12,ii} = 4 \epsilon_{ii} \sigma_{ii}^{12}$ (单位:kJ mol⁻¹ nm¹²) 此时 Lennard-Jones 势能通常写作: \[V_{LJ}(r) = \frac{C_{12,ij}}{r^{12}} - \frac{C_{6,ij}}{r^6}\] 如果 comb-rule = 2 或 3: $V_{ii}$ 直接代表 $\sigma_{ii}$ (单位:nm) $W_{ii}$ 直接代表 $\epsilon_{ii}$ (单位:kJ mol⁻¹) 此时 Lennard-Jones 势能通常写作: \[V_{LJ}(r) = 4 \epsilon_{ij} \left[\left(\frac{\sigma_{ij}}{r}\right)^{12} - \left(\frac{\sigma_{ij}}{r}\right)^6\right]\] 2. 交叉项参数的计算 (如果未在 [nonbond_params] 中显式定义) 对于 comb-rule = 1 和 3: GROMACS 使用几何平均来组合 $C_6$ 和 $C_{12}$ 参数: \[C_{6,ij} = \sqrt{C_{6,ii} \times C_{6,jj}}\] \[C_{12,ij} = \sqrt{C_{12,ii} \times C_{12,jj}}\] 注意:如果 comb-rule = 3,[atomtypes] 中的 $V_{ii}$ 和 $W_{ii}$ 被解释为 $\sigma_{ii}$ 和 $\epsilon_{ii}$。GROMACS 内部会先将它们转换为 $C_{6,ii}$ 和 $C_{12,ii}$,然后再应用上述几何平均规则。 对于 comb-rule = 2 (Lorentz-Berthelot 规则): GROMACS 使用算术平均组合 $\sigma$ 参数,使用几何平均组合 $\epsilon$ 参数: \[\sigma_{ij} = \frac{\sigma_{ii} + \sigma_{jj}}{2}\] \[\epsilon_{ij} = \sqrt{\epsilon_{ii} \times \epsilon_{jj}}\] 关于常见力场的组合规则说明 注意:常见力场(CHARMM、AMBER、OPLS等)与 GROMACS 中 comb-rule 参数的对应关系在文献中并不十分明晰,以下信息基于有限的资料整理推测: 力场 σ 组合规则 ε 组合规则 可能的 GROMACS 设置 备注 CHARMM 算术平均 几何平均 comb-rule = 2 如果 [atomtypes] 中提供的是 $\sigma_{ii}$ 和 $\epsilon_{ii}$ AMBER 算术平均 几何平均 comb-rule = 2 明确使用 Lorentz-Berthelot 规则 OPLS 几何平均 几何平均 comb-rule = 3 通常在 [nonbond_params] 中显式定义所有交叉项 算术平均是Lorentz提出的,几何平均是Berthelot提出的 也就是说,comb-rule = 1当然是万能的,但全原子一般是给出 $\sigma$ 和 $\epsilon$,其中comb-rule = 2 即Lorentz-Berthelot 规则,comb-rule = 3 即均为几何平均。 CHARMM:使用 Lorentz-Berthelot 规则。对 $\sigma$ (或NAMD里面,等效的 $R_{min}$) 使用算术平均,对 $\epsilon$ 使用几何平均。 \(R_{min,ij} = \frac{R_{min,ii} + R_{min,jj}}{2} \text{(等效于 $\sigma$ 的算术平均)}\) \[\epsilon_{ij} = \sqrt{\epsilon_{ii} \times \epsilon_{jj}}\] 参考:NAMD Mailing List - https://www.ks.uiuc.edu/Research/namd/mailing_list/namd-l.2009-2010/3885.html AMBER:明确使用 Lorentz-Berthelot 规则。根据 AMBER 手册节选:”For Amber force fields, cross terms involving different atom types i and j are evaluated according to the Lorentz/Berthelot mixing rules…“,可以自行查找 OPLS:OPLS 力场通常对 Lennard-Jones 参数 $\sigma$ 和 $\epsilon$ 都使用几何平均。 OPLS 力场的 GROMACS 实现通常没有 [nonbond_params] 。 NAMD参考文末 二、[atomtypes] 和 [nonbond_params] 中的参数解释 GROMACS 通过 [atomtypes] 和 [nonbond_params] (或 [pairtypes]) 这两个主要部分来定义非键相互作用参数。 参考:GROMACS Manual - Non-bonded parameters - https://manual.gromacs.org/current/reference-manual/topologies/parameter-files.html#non-bonded-parameters [atomtypes] 部分 此部分定义了每种原子类型自身 (ii) 的基本非键参数。这些参数的解释(是 $\sigma$, $\epsilon$ 还是 $C_6$, $C_{12}$)取决于 [defaults] 中设置的 comb-rule。 示例 (OPLS-AA 风格,通常 comb-rule = 1,意味着 V, W 是 $C_6$, $C_{12}$) [ atomtypes ] ;name at.num mass charge ptype V(c6) W(c12) ; V 和 W 的含义取决于 comb-rule O 8 15.99940 0.000 A 0.22617E-02 0.74158E-06 ; V(c6) = C6_ii, W(c12) = C12_ii OM 8 15.99940 0.000 A 0.22617E-02 0.74158E-06 ... [nonbond_params] 部分 此部分用于显式定义特定原子类型对 i 和 j 之间的非键相互作用参数。这里定义的参数将覆盖任何通过组合规则计算得到的参数。 示例1 ( comb-rule = 1 配合,参数为直接的 $C_{6,ij}$ 和 $C_{12,ij}$) [ nonbond_params ] ; i j func V(c6) W(c12) ; 列标题指明了是 C6 和 C12 O O 1 0.22617E-02 0.74158E-06 ; O-O 相互作用的 C6_ij 和 C12_ij O OA 1 0.22617E-02 0.13807E-05 ; O-OA 相互作用的 C6_ij 和 C12_ij ... V(c6):该原子类型对的 Lennard-Jones $C_{6,ij}$ 参数 (单位:kJ mol⁻¹ nm⁶)。 W(c12):该原子类型对的 Lennard-Jones $C_{12,ij}$ 参数 (单位:kJ mol⁻¹ nm¹²)。 示例2 (Martini 风格,参数为直接的 $\sigma_{ij}$ 和 $\epsilon_{ij}$) [ nonbond_params ] ; i j func sigma epsilon ; 列标题通常会指明是 sigma 和 epsilon P6 P6 1 0.470 4.990 ; P6-P6 相互作用的 sigma_ij 和 epsilon_ij P6 P5 1 0.470 4.730 ; P6-P5 相互作用的 sigma_ij 和 epsilon_ij ... i, j:相互作用的原子类型。 func:函数类型,1 表示 Lennard-Jones 12-6 势。 sigma:该原子类型对的 Lennard-Jones $\sigma_{ij}$ 参数 (单位:nm)。 epsilon:该原子类型对的 Lennard-Jones $\epsilon_{ij}$ 参数 (单位:kJ/mol)。 关键点:[nonbond_params] 中参数的含义(是 $\sigma$/$\epsilon$ 还是 $C_6$/$C_{12}$)直接由该力场文件在该部分的列定义(通常通过注释中的列标题)决定。func=1 只是表示它是一个12-6型的Lennard-Jones势,但参数的表达形式可以有两种。 三、Martini 力场的特殊性 对于 Martini 力场 (例如 martini_v3.0.0.itp): 参考文献:PCT Souza, et al., Nat. Methods, 2021. DOI:10.1038/s41592-021-01098-3 (看SI的表) [defaults] 指令 Martini 3 的主 .itp 文件通常包含: [ defaults ] ; nbfunc comb-rule 1 2 ; (通常 gen-pairs no, fudgeLJ/QQ 不适用或设为1.0) 这里的 comb-rule = 2 设定了默认的参数类型。 [atomtypes] 部分(真实示例) 在 Martini 3 中,[atomtypes] 部分的 $\sigma$ 和 $\epsilon$ 值都设为 0.0,因为 Martini 的核心在于珠子类型之间的相互作用矩阵: [ atomtypes ] ; name mass charge ptype sigma epsilon P6 72.0 0.000 A 0.0 0.0 P5 72.0 0.000 A 0.0 0.0 ... 这里的 sigma 和 epsilon 都是 0.0,表明它们仅是占位符。 [nonbond_params] 部分(真实示例) 这是 Martini 力场定义非键相互作用的关键。Martini 不依赖 GROMACS 的组合规则来生成不同珠子类型之间的相互作用参数。相反,它在 [nonbond_params] 部分显式地定义每一对珠子类型之间的 $\sigma_{ij}$ 和 $\epsilon_{ij}$: [ nonbond_params ] P6 P6 1 4.700000e-01 4.990000e+00 P6 P5 1 4.700000e-01 4.730000e+00 ... 注意这里: 没有列标题注释,但根据 Martini 文档,这些参数是 $\sigma_{ij}$ (第4列) 和 $\epsilon_{ij}$ (第5列) 所有珠子对的相互作用都被显式定义 因此,当 grompp 处理 Martini 拓扑时,它会优先使用 [nonbond_params] 中为特定珠子对定义的 $\sigma_{ij}$ 和 $\epsilon_{ij}$。只有当某一对珠子类型的相互作用没有在 [nonbond_params] 中显式定义时,才会退回到使用 [defaults] 中指定的 comb-rule 和 [atomtypes] 中的参数来尝试计算(但由于 [atomtypes] 中的值都是 0.0,实际上不会产生有意义的相互作用)。 详见上一篇: 总结 对于标准的 Martini 3 力场文件: [atomtypes] 中的 $\sigma$/$\epsilon$ 都是 0.0:它们是占位符,不用于计算。 核心的异类珠子对相互作用参数来自 [nonbond_params]:这是Martini设计的核心。 [nonbond_params] 中提供的是针对特定珠子对 ij 的 $\sigma_{ij}$ 和 $\epsilon_{ij}$:这些不是 $C_{6,ij}$ 和 $C_{12,ij}$。 [defaults] 中的 comb-rule = 2 在 Martini 中更多的是一个形式上的设定:因为所有相关的珠子对相互作用参数都是在 [nonbond_params] 中显式提供的。 四、总结:如何判断参数类型 判断 .itp 文件中非键参数是 ($\sigma$, $\epsilon$) 还是 ($C_6$, $C_{12}$) 的关键步骤: 1. 查看 [defaults] 指令中的 comb-rule 如果 comb-rule = 1,那么 [atomtypes] 中的 V 和 W 列倾向于是 $C_{6,ii}$ 和 $C_{12,ii}$。 如果 comb-rule = 2 或 3,那么 [atomtypes] 中的 V 和 W 列倾向于是 $\sigma_{ii}$ 和 $\epsilon_{ii}$。 2. 仔细阅读 [atomtypes] 和 [nonbond_params] 部分的列标题注释 如果列标题明确写着 sigma 和 epsilon,那么这些值就是 $\sigma$ 和 $\epsilon$。 如果列标题明确写着 V(c6) 和 W(c12),那么这些值就是 $C_6$ 和 $C_{12}$。 假定开发者不至于搞错,这是最直接的判断依据。 3. 查阅相应力场的原始文献和手册 这是最权威的判断依据。力场开发者会明确说明其参数的定义和使用方式。 实用建议 对于您的脚本而言,如果它需要同时处理可能来自不同力场的 .itp 文件,建议: 通过一个参数来指定当前处理的ITP文件中的非键参数是哪种类型 或者通过智能解析列标题来判断 对于 Martini 这样的特殊情况([atomtypes] 中都是 0.0),直接使用 [nonbond_params] 中的参数 其他参考资料 GROMACS Manual - MDP Options for LJ-PME combination rule: https://manual.gromacs.org/current/user-guide/mdp-options.html#mdp-lj-pme-comb-rule NAMD 的相关设置 NAMD Mailing List:https://www.ks.uiuc.edu/Research/namd/mailing_list/namd-l.2009-2010/3885.html “Yes, as is standard for the CHARMM force field NAMD uses arithmetic mean for sigma, geometric mean for epsilon by default. You can change this by adding ‘vdwGeometricSigma yes’ in the config file to support, e.g., OPLS.” NAMD User Guide:https://www.ks.uiuc.edu/Research/namd/3.0.1/ug/node25.html#7012 “vdwGeometricSigma:Use geometric mean, as required by OPLS, rather than traditional arithmetic mean when combining Lennard-Jones sigma parameters for different atom types.”
Techniques
· 2025-10-08
【笔记整理|2024年上半年】科学可视化工具实用技巧集锦
【笔记整理|2024年上半年】科学可视化工具实用技巧集锦 VMD使用技巧 基本设置与渲染 渲染模式优化: VMD默认使用称作Normal的Rendermode,但此时有些材质的显示效果很差,甚至Transparent材质根本没法正确显示出透明效果。因此通过以下命令将默认的Rendermode设为效果好得多的GLSL: display rendermode GLSL VMD脚本与命令 TCL脚本中执行bash命令: 可以在TCL脚本中直接执行bash命令: exec grep 'ATOM' ${i}.pdb >> ${outputFile} 动画控制: animate goto 296 播放MVD文件: play view.mvd VMD路径与集成 Windows上的VMD路径: /mnt/c/Program\ Files/VMD/vmd.exe 在WSL中使用Windows版VMD: alias vmd='vmd.exe' VMD插件路径: /lib/vmd/plugins/LINUXAMD64/bin/catdcd5.2 VMD坐标变换 transabout命令详解 语法和参数: # 绕指定轴和向量旋转的变换矩阵 transabout v amount [deg|rad|pi] 参数说明: v:旋转轴向量,格式为 {x y z},如 {0 0 1} 表示绕Z轴旋转 amount:旋转角度的数值 deg|rad|pi:角度单位,分别表示度、弧度或π的倍数 实际应用示例: # 绕Z轴旋转90度 set rot_matrix [transabout {0 0 1} 90 deg] # 绕任意向量{1 1 1}旋转π/4弧度 set rot_matrix [transabout {1 1 1} 0.25 pi] # 应用变换到原子选择 set sel [atomselect top "protein"] $sel move $rot_matrix 变换原理:生成绕通过原点沿给定向量的轴逆时针旋转指定角度的4x4齐次变换矩阵,可以与其他变换(平移、缩放)组合使用。 VMD变换命令文档: https://www.ks.uiuc.edu/vmd/current/ug/node194.html 嵌套列表处理问题详解 问题背景:VMD中获取原子坐标时经常遇到嵌套列表格式问题,这是VMD Tcl脚本编程中的常见陷阱。 问题表现: # 错误的坐标格式(嵌套列表) set coords [$atm get {x y z}] # 结果: {{10.5 20.3 30.7}} - 注意双重大括号! # 期望的格式(简单列表) # 结果: {10.5 20.3 30.7} - 单层大括号 为什么会出现嵌套列表: VMD的get命令返回的是列表的列表 每个原子的坐标作为一个子列表存储 即使只有一个原子,也会返回包含一个元素的列表 解决方案: # 方法1:使用lindex提取第一个元素 set coord1 [lindex [$atm get {x y z}] 0] # 方法2:处理多个原子的坐标 set sel [atomselect top "protein"] set coords [$sel get {x y z}] foreach coord $coords { set x [lindex $coord 0] set y [lindex $coord 1] set z [lindex $coord 2] # 处理单个原子坐标 } # 方法3:计算两点间距离的完整示例 set sel1 [atomselect top "resid 1 and name CA"] set sel2 [atomselect top "resid 10 and name CA"] set coord1 [lindex [$sel1 get {x y z}] 0] set coord2 [lindex [$sel2 get {x y z}] 0] set distance [vecdist $coord1 $coord2] VMD用户邮件列表参考: https://www.ks.uiuc.edu/Research/vmd/mailing_list/vmd-l/2584.html 高级坐标变换技巧 组合变换: # 先平移再旋转 set trans_matrix [transoffset {5 0 0}] # 沿X轴平移5埃 set rot_matrix [transabout {0 0 1} 45 deg] # 绕Z轴旋转45度 set combined_matrix [transmult $rot_matrix $trans_matrix] $sel move $combined_matrix 分子对齐: # 将分子质心移到原点,然后旋转 set sel [atomselect top "backbone"] set center [measure center $sel] set trans_to_origin [transoffset [vecscale -1 $center]] $sel move $trans_to_origin $sel move $rot_matrix PyMOL操作指南 基本操作 菜单操作: 启动VMD后按”Push Menus” 蛋白质轨迹对齐: 在PyMOL中,使用intra_fit命令将蛋白质轨迹对齐到第一帧: intra_fit PyMOL设置优化 正交投影设置: set orthoscopic, on PyMOL正交投影文档: https://pymolwiki.org/index.php/Orthoscopic PyMOL轨迹制作 电影制作教程: PyMOL电影制作指南: https://pymol.org/tutorials/moviemaking/ PyMOL提供了完整的轨迹电影制作功能,适合制作高质量的分子动画。 ChimeraX高级功能 视图设置 正交视图: camera ortho 相机设置文档: ChimeraX相机命令: https://www.cgl.ucsf.edu/chimerax/docs/user/commands/camera.html 晶胞显示 显示晶胞轮廓: unitcell outline 这对于显示周期性边界条件下的分子动力学模拟结果特别有用。 尺寸控制 对象尺寸调整: ChimeraX尺寸命令文档: https://www.cgl.ucsf.edu/chimerax/docs/user/commands/size.html PBC盒子显示 在Chimera中显示蛋白质-配体系统周围的PBC盒子/单元晶胞,这对于MD模拟结果的可视化很重要。可以用于录制MD模拟后的影片。 螺旋圆柱显示 ChimeraX提供了螺旋圆柱显示功能,可以更好地展示蛋白质的二级结构。 ChimeraX螺旋圆柱命令文档: https://www.cgl.ucsf.edu/chimerax/docs/user/commands/spiral.html 系统兼容性检查 WSL中的显示问题: WSL中的VMD,display功能无法正常显示任何内容,建议使用原生Linux版本或Windows版本。 如果PyMOL和ChimeraX都有问题,那就是系统级别的问题。需要检查: 显卡驱动是否正常 OpenGL支持是否完整 系统库文件是否缺失 分子结构文件处理 坐标文件转换 从坐标和拓扑文件生成PDB: ambpdb -p topology-file < coordinates-file > filename.pdb Amber文件转换示例: ambpdb -p cram.prmtop -c min_qmmm.rst > min_qmmm.rst.pdb 分子重心平移 将mol2文件的质心平移到(0,0,0)是常见的分子预处理操作,可以通过坐标计算和平移实现。 轨迹分析与可视化 文件上传与目录结构保持 上传所有mapping.png文件并保持父目录结构时,简单的scp不太理想。更强大简洁的方法是结合tar和ssh: tar -czf - mapping.png | ssh user@remote 'cd /target/dir && tar -xzf -' 主成分轴长度计算 在MDAnalysis中计算蛋白质三个主成分轴的长度: import MDAnalysis as mda # 计算惯性张量和主成分轴 # 然后计算每个轴的长度 这对于分析蛋白质形状变化很有用。 数据可视化选择 图表库选择 在现代web开发中,推荐使用: Tailwind CSS:用于布局和样式设计 Chart.js:用于标准图表 Plotly.js:用于复杂图表,确保使用Canvas/WebGL渲染 所有图表和图示都应该避免使用SVG和Mermaid JS,转而使用HTML/CSS、Unicode字符或Canvas来实现。 分子网格显示 mols2grid使用: import mols2grid # 显示和滚动浏览聚类样本 mols2grid.display(molecules) 这对于大量分子的筛选和比较非常有用。 小结 科学可视化工具的选择和配置对研究效率有重要影响。VMD适合复杂的轨迹分析和脚本化操作,PyMOL在分子图形制作方面表现出色,ChimeraX则提供了现代化的用户界面和强大的渲染能力。正确配置这些工具,结合合适的数据处理流程,能够显著提升科学研究中的可视化质量和效率。同时,了解跨平台兼容性问题和性能优化技巧,有助于构建稳定高效的可视化工作环境。
Techniques
· 2025-10-08
【笔记整理|2024年上半年】分子动力学模拟实用技巧与经验总结
【笔记整理|2024年上半年】分子动力学模拟实用技巧与经验总结 MD模拟技巧 轨迹分析与处理 Amber轨迹重启时间设置问题 ncdump -v time [path to your rst7 file] 当重启模拟时,初始时间从重启文件中读取。可以用上述命令检查重启文件中的时间设置。 Amber轨迹文件合并 使用cpptraj工具合并多个.nc轨迹文件: cpptraj -p topology.prmtop trajin file1.nc trajin file2.nc trajout combined.nc cpptraj是AmberTools套件中处理轨迹文件的多功能程序,可以处理包括合并在内的各种操作。 温度耦合组优化设置 在GROMACS中,温度耦合组(tc-grps)的设置需要根据体系各组分的动力学特性进行合理分组,以平衡温度控制的精度和计算效率。针对脂双层膜-水-溶质体系,建议: 脂质分子单独成组 水分子单独成组 蛋白质/小分子溶质单独成组 动态负载平衡设置 -dlb auto # 默认开启 -dlb yes # 显式指定 在粒子分布不均或相互作用强度不同的情况下动态调整域大小。 注意:在GPU常驻模式(使用-update gpu)时,动态负载平衡会被关闭。 伞形采样与PMF计算 拉动参数优化 拉动力常数建议 拉动力常数建议设置在1000-5000之间比较合适,需要根据具体体系进行调试。 收敛性检查 gmx wham -b 50000 # 只包含最后50ns gmx wham -b 75000 # 只包含最后25ns 检查收敛性时,可以只包含每个模拟的最后50ns或25ns数据,通过-b选项控制。 PMF解读注意事项 PMF表面上最多计数的区域不一定对应能量最小值。这是因为PMF模拟施加了偏置势来采样特定区域,在能量计算时会去除这个偏置。如果用”无偏”模拟估算自由能,最小值才对应最大采样区域。 伞形采样窗口设置 结合位点附近窗口密度 对于蛋白质-配体结合体系,可能需要在结合位点附近设置更多的窗口,而不是单纯延长每个窗口的模拟时间。 长距离拉动设置 Direction-periodic选项应该只用于需要拉动超过半个盒子长度距离的情况。这种情况很少见,拉动大型聚合物可能是一个有效的使用场景。建议拉动距离略小于完整盒子尺寸,以避免周期性映像间的相互作用。 Martini粗粒化力场 Martini 3.0 参数和设置 Colvars使用 Colvars: https://colvars.github.io - 集合变量库,可用于增强采样和自由能计算。 Martini 3.0甾醇参数 Martini 3.0甾醇参数: https://github.com/Martini-Force-Field-Initiative/M3-Sterol-Parameters/blob/main/martini_v3.0_sterols_v1.0.itp Martini 3.0脂质参数 Martini脂质参数库: https://github.com/Martini-Force-Field-Initiative/M3-Lipid-Parameters 镁离子表示 镁离子用一个TQ3p珠子表示,带电荷+1。 几何结合规则设置 vdWGeometricSigma参数 vdwGeometricSigma yes 在Martini力场中使用几何结合规则计算范德华相互作用参数。 NAMD高级应用 多拷贝/副本交换设置 多拷贝副本交换脚本接口 NAMD提供专门的脚本接口用于多拷贝/副本交换模拟设置。 命令行参数传递 namd3 --outputenergies 100 --run 100 可以通过–keyword value参数对直接在命令行指定配置参数。 配置文件路径管理 工作目录自动切换 执行时NAMD会自动切换到包含配置文件的目录,使配置文件中的所有文件路径都相对于配置文件目录。可以指定多个配置文件,但所有文件路径都相对于第一个调用”run”命令的配置文件,或如果没有调用”run”则相对于最后一个配置文件。 轨迹可视化技巧 ChimeraX使用技巧 正交投影设置 camera ortho 在ChimeraX中设置正交投影视图,便于科学可视化。 晶胞显示 unitcell outline 显示周期性边界条件的晶胞轮廓。 调整显示尺寸 参考ChimeraX尺寸命令文档: https://www.cgl.ucsf.edu/chimerax/docs/user/commands/size.html PyMOL轨迹制作 PyMOL轨迹电影制作 参考PyMOL电影制作教程: https://pymol.org/tutorials/moviemaking/ PyMOL正交投影设置 PyMOL正交投影文档: https://pymolwiki.org/index.php/Orthoscopic GROMACS选择语法 距离计算和选择 距离计算命令 gmx distance -s md_smd.tpr -f md_smd.xtc -n index.ndx -oav dist.xvg 计算指定原子组间的距离变化。 gmx select工具 gmx select # 基本动态选择数据输出 gmx help selections # 详细选择语法帮助 gmx select可以输出动态选择的基本数据,用于简单分析或与其他程序组合进行更复杂的计算。 编译与安装问题 库文件依赖解决 glibc库链接问题 ln -s /usr/lib64/libz.so.1 /path/to/glibc/lib ln -s /usr/lib64/libstdc++.so.6 /path/to/glibc/lib ln -s /usr/lib64/libgcc_s.so.1 /path/to/glibc/lib 编译安装新版本glibc时,需要手动链接系统中的其他必要库文件。 CUDA兼容性 CUDA 12.2支持 CUDA版本12.2已被检测到,需要相应修改cmake/CudaConfig.cmake配置文件以确保兼容性。 相关资源 GROMACS社区 GROMACS论坛: https://gromacs.bioexcel.eu - GROMACS官方技术支持论坛 GROMACS PMF讨论: https://gromacs.bioexcel.eu/t/how-can-i-get-smooth-pmf-from-umbrella-sampling/3629 伞形采样直方图问题: https://gromacs.bioexcel.eu/t/problem-with-umbrella-histograms/9216 技术博客 GROMACS分子间相互作用计算: https://jerkwin.github.io/2019/09/06/%E4%BD%BF%E7%94%A8GROMACS%E8%AE%A1%E7%AE%97%E5%88%86%E5%AD%90%E9%97%B4%E7%9B%B8%E4%BA%92%E4%BD%9C%E7%94%A8/ 小结 分子动力学模拟涉及众多技术细节,从参数设置到结果分析都需要丰富的经验积累。合理的温度耦合、动态负载平衡、以及针对性的采样策略是获得可靠结果的关键。同时,可视化工具的熟练使用能够帮助更好地理解模拟结果和发现问题。
Techniques
· 2025-10-08
【笔记整理|2023-09】VMD和PyMOL分子可视化实用技巧
【笔记整理|2023-09】VMD和PyMOL分子可视化实用技巧 分子可视化是结构生物学和计算化学研究中的重要环节。本文总结了在VMD和PyMOL使用过程中的实用技巧和常见问题解决方案。 VMD使用技巧 WSL环境下使用Windows VMD 在WSL (Windows Subsystem for Linux) 中可以直接调用Windows版本的VMD,避免Linux版本的安装和配置问题: # 设置别名以便使用 alias vmd='vmd.exe' # 或者使用完整路径 /mnt/c/Program\ Files/VMD/vmd.exe 注意事项: 加载分子时需要使用Windows路径格式 vmd.exe 在WSL中可以正常工作 路径中包含空格的需要用反斜杠转义 VMD基本操作技巧 启动和界面 # 启动后按"Push Menus"来显示菜单 press "Push Menus" after vmd startup 分子显示控制 显示/隐藏分子:双击分子列表中的”D”(Display)来显示或隐藏分子 当D灰化时,分子被隐藏;双击D可以切换显示状态 分子对齐技巧 将蛋白质主向量对齐到z轴,便于分析和可视化: # 计算分子的惯性矩和主轴 set sel [atomselect top "protein"] set I [inertia $sel] set eigenvecs [lindex $I 2] set z_axis {0 0 1} # 对齐到z轴 set transformation [transvecinv [lindex $eigenvecs 2]] $sel move $transformation 轨迹分析和动画制作 轨迹导航 # 跳转到特定帧 animate goto 296 # 播放预设的视角动画 play view.mvd 制作分子动画 VMD MovieMaker插件可以制作高质量的分子动画: # 加载MovieMaker插件 package require vmdmovie # 基本设置 set MovieMaker::renderer tachyon set MovieMaker::framerate 30 set MovieMaker::movietype trajectory set MovieMaker::trjstep 200 # 通常使用30帧就够了 # 生成动画 MovieMaker::buildmovie 动画制作技巧: 较大的屏幕尺寸可以提高动画清晰度,但提升不是很明显 合理设置帧间隔(trjstep)来平衡文件大小和流畅度 常见问题解决 残基处理问题 甘氨酸N端如果出现”failed to guess coordinates for HA”错误: # 使用GLYP残基类型代替GLY PRES GLYP 1.00 ! Glycine N-terminus 猜测坐标的原子occupancy会被设为0.0 GLYP专门用于处理甘氨酸N端的坐标生成问题 插件和工具 # catdcd工具位置 /lib/vmd/plugins/LINUXAMD64/bin/catdcd5.2 # VMD movie制作脚本位置 /opt/vmd1.9.4a57/lib/vmd/plugins/noarch/tcl/vmdmovie1.9/vmdmovie.tcl PyMOL使用技巧 基础显示和预设 蛋白质界面分析 使用预设显示蛋白质界面:A → preset → protein interface 二硫键显示 PyMOL有专门的二硫键显示功能: 点击”S”菜单 将光标移到”disulfides” 选择想要的表示方式显示二硫键 透明水盒子绘制 在分子动力学体系可视化中,经常需要显示透明的水盒子来展示溶剂环境。 结构分析功能 序列搜索和对齐 findseq命令:用于在结构中搜索特定序列 参考:PyMOL Findseq文档:https://pymolwiki.org/index.php/Findseq mcsalign命令:用于多个结构的对齐 参考:PyMOL Mcsalign文档:https://pymolwiki.org/index.php/Mcsalign RMSD矩阵计算 对于多个PDB文件的配对RMSD分析: 使用PyMOL API计算配对RMSD矩阵(对齐后) 可以批量处理多个PDB文件 生化性质显示 显示蛋白质的生化性质(如疏水性、电荷分布等): 参考:PyMOL生化性质显示指南:https://pymolwiki.org/index.php/Displaying_Biochemical_Properties 脚本和自动化 从脚本启动 PyMOL支持从脚本启动和批量操作: 参考:从脚本启动PyMOL:https://pymolwiki.org/index.php/Launching_From_a_Script 比较:VMD vs PyMOL VMD的优势 轨迹分析:优秀的轨迹播放和分析功能 大体系处理:处理大型分子体系性能更好 插件丰富:大量的分析和可视化插件 脚本化:Tcl脚本支持强大的自动化功能 PyMOL的优势 图像质量:更精美的渲染效果 易用性:更直观的用户界面 结构分析:丰富的结构比较和分析工具 出版质量:更适合制作论文插图 建议使用场景 MD轨迹分析:优先使用VMD 静态结构展示:优先使用PyMOL 批量处理:VMD的Tcl脚本更灵活 交互式分析:PyMOL界面更友好 文件格式兼容性 跨平台注意事项 VMD在Windows和Linux间加载分子时注意路径格式差异 某些插件可能对路径中的空格敏感 建议使用标准PDB格式以确保兼容性 轨迹文件处理 使用catdcd等工具进行轨迹格式转换 注意不同MD程序输出格式的差异 大轨迹文件可能需要分段处理 性能优化建议 VMD性能优化 合理设置显示级别,避免显示过多细节 使用选择表达式限制显示的原子数量 大轨迹分析时适当跳帧 PyMOL性能优化 复杂场景可以关闭实时渲染 使用LOD(Level of Detail)控制显示精度 批量操作时使用命令行模式 扩展资源 官方文档 VMD用户指南:https://www.ks.uiuc.edu/Research/vmd/current/ug/ PyMOL Wiki:https://pymolwiki.org 社区资源 VMD邮件列表:https://www.ks.uiuc.edu/Research/vmd/mailing_list/ PyMOL讨论区:https://pymolwiki.org/index.php/Category:Script_Library 本文基于2023年9-12月技术讨论记录整理,包含实际使用中遇到的问题和解决方案
Techniques
· 2025-10-08
【笔记整理|2023-09】Amber和GROMACS分子动力学模拟实用指南
【笔记整理|2023-09】Amber和GROMACS分子动力学模拟实用指南 本文总结了在使用Amber、GROMACS和NAMD进行分子动力学模拟时的实用技巧、常见问题和最佳实践。 AmberTools使用经验 版本更新和兼容性 AmberTools22改进 AmberTools22解决了早期版本的Python兼容性问题 参数生成工具改进 parmchk2 vs parmchk: parmchk2(Amber14引入)比parmchk更优秀 parmchk2对所有子结构进行搜索打分,比较所有参数后选择最适合的参数 parmchk只检查某几个子结构的参数文件来获取缺失参数 # 使用parmchk2生成缺失参数 parmchk2 -i ligand.mol2 -f mol2 -o ligand.frcmod AmberTools更新管理 # 更新AmberTools ./update_amber --update # 检查可用的bug修复 # 参考:[Amber Bug修复页面](https://ambermd.org/BugFixes.php):https://ambermd.org/BugFixes.php 小分子参数化 antechamber使用 # 从Gaussian输出文件生成mol2文件 antechamber -i bay.log -fi gout -o bay.mol2 -fo mol2 # acpype工具依赖关系问题 # acpype依赖于AmberTools但Amber不包含acpype # 通过conda安装会获取另一个ambertools版本 # 解决方案:在base环境中使用pip安装 pip install acpype GROMACS使用技巧 性能优化 GPU使用限制 GROMACS大部分体系用多GPU,和单GPU比很难获得有效的提升 GROMACS 4.6.x后支持CPU/GPU混合模式 短程非键相互作用在GPU上计算,长程和键相互作用在CPU上计算 通过调整短程相互作用截断距离来优化GPU/CPU负载平衡 建议GROMACS版本选择 # 对于PLUMED用户,建议使用GROMACS 2022.5而非2023版本 gq says use gmx 2022.5 instead of 2023 for plumed 常见操作命令 基础模拟运行 # 能量最小化 gmx mdrun -deffnm em_tpr # 自由能计算脚本示例 bash gmx_fep_re_sep_conti.sh WT-M132-re quick 3 2>error.log 力场和膜体系 CHARMM36力场移植 CHARMM36 GROMACS移植讨论:https://gromacs.bioexcel.eu/t/newest-charmm36-port-for-gromacs/868/9 注意力场兼容性和参数一致性问题 膜体系模拟设置 推荐设置来避免生物分子跑出盒子: # 在mdp文件中设置 comm-grps = protein comm-mode = angular 这样可以持续消除蛋白质的平动和转动。 膜体系构建最佳实践 构建工具对比 PACKMOL的局限性 虽然也可以用Packmol构建蛋白质、核酸浸在溶剂环境中的体系,但是这样做明显不如用动力学程序自带的专用工具好,因为: - Packmol产生的水的密度偏低 - 水的分布特征和实际体相水相差较大 - NPT模拟后盒子变形、收缩得厉害 - 可能出现溶质与其镜像最近距离太近的问题 推荐构建方法 使用MD程序专用的溶剂化工具: # GROMACS推荐使用gmx solvate # 使用事先NPT平衡好的溶剂盒子(如spc216.gro) # 通过平移复制来填充真空区,溶剂分布更理想 Amber膜体系构建 可用工具和力场 构建Amber膜体系的工具选择: AMBAT:Amber自带工具 CHARMM-GUI:图形界面,支持多种力场 DABBLE:第三方工具 PACKMOL-Memgen:最新推荐工具 LIPID21力场: LIPID21 is the latest and recommended lipid force field. 力场兼容性 Stockholm lipids (SLipids): Parameters are available for saturated and unsaturated PC, PS, PE, PG, SM lipids and cholesterol. They are supposed to work with AMBER99SB/AMBER99SB-ILDN/AMBER03/GAFF FF for proteins and small molecules. 在CHARMM-GUI中使用Amber力场 回答”setup a lipid bilayer full of popc in Amber force field with charmm-gui”的问题: 在Force Field Options步骤中可以选择Amber力场,这是在任何构建模块的最后一步(通常是输入生成步骤)。 磷脂分子理解 sn-2位置含义 sn-2 hydrocarbon in phospholipid指磷脂分子甘油骨架上第二个碳原子所连接的脂肪酸链。 sn来自stereochemical numbering(立体化学编号),用于区分甘油分子的三个碳原子位置。 高级功能和技巧 牵引和约束 GROMACS Pull Code 使用pull code在配体和脂质双分子层质心之间添加距离约束: # 在mdp文件中设置pull参数 pull = yes pull_ngroups = 2 pull_group1_name = ligand pull_group2_name = membrane_com pull_coord1_type = distance pull_coord1_geometry = distance PLUMED集成 # PLUMED使用与GROMACS相同的内部单位 PLUMED internal units: the same as gromacs # 在PLUMED中添加约束的示例 RESTRAINT ARG=d1 KAPPA=1000 AT=2.0 力场开发和修改 GROMACS力场扩展性问题 rtp文件其实并不难写,和rtf的复杂度几乎相同,扩展参数的复杂度和prm也基本相同。 问题是gmx建模的可扩展性极差,频繁更改力场文件令人难以接受,所以也没人开发自动转化为rtp等格式、自动加入gmx格式力场的程序。 解决方案 对非聚合物体系,暂且忍受现有限制 对特殊聚合物,往往需要用VMD/tleap建模再转换 对偶尔使用的residue,手动添加到GROMACS力场中 常见错误和解决方案 编译和安装问题 Boost库依赖 # 检查Boost版本和组件 Found Boost: /path/to/anaconda3/envs/AMBER22/lib/cmake/Boost-1.78.0/BoostConfig.cmake (found version "1.78.0") found components: thread system program_options iostreams regex timer chrono filesystem graph 构建工具链问题 # cgenff工具编译 pyinstaller -F cgenff_charmm2gmx_py3_nx2.py 文件格式和拓扑问题 GROMACS vs Amber拓扑差异 只有GROMACS在.top文件中可能有moleculetype(Amber/NAMD:列出所有原子), 所以从其他程序转换的拓扑只能列出所有原子,使得复杂约束生成非常困难! sed脚本处理拓扑 # 在topol.top中添加包含文件 sed -i "/\#endif/a\#include \"LIG.itp\"" topol.top sed -i "/\#endif/a\n\#include \"LIG.itp\"" topol.top 资源和参考 官方教程 Amber基础教程4b:https://ambermd.org/tutorials/basic/tutorial4b/ Amber膜体系教程:https://ambermd.org/tutorials/MembraneSystems.php Amber高级教程16:https://ambermd.org/tutorials/advanced/tutorial16/ Amber高级教程38:https://ambermd.org/tutorials/advanced/tutorial38/index.php 第三方资源 AMBER antechamber指南:https://emleddin.github.io/comp-chem-website/AMBERguide-antechamber.html PACKMOL用户指南:https://m3g.github.io/packmol/userguide.shtml GROMACS伞型采样教程:https://group.miletic.net/en/tutorials/gromacs/5-umbrella/ 社区讨论 GROMACS论坛:https://gromacs.bioexcel.eu Amber邮件列表:http://archive.ambermd.org 总结 选择合适的MD程序和工具组合是成功进行分子模拟的关键: Amber: 适用于生物分子体系,参数化工具成熟 GROMACS: 高性能,适合大规模并行计算 NAMD: 灵活的参数控制,适合复杂体系 建议根据具体研究需求和计算资源选择最合适的工具组合。 本文基于2023年9-12月技术讨论记录整理,涵盖实际模拟中遇到的问题和解决方案
Techniques
· 2025-10-08
【笔记整理|2023-09+2024年上半年】RDKit和Gaussian计算化学工具使用经验
【笔记整理|2023-09+2024年上半年】RDKit和Gaussian计算化学工具使用经验 本文总结了在使用RDKit进行化学信息学处理和Gaussian进行量子化学计算时的实用技巧、常见问题和解决方案。 RDKit分子处理 基础分子操作 分子导入和基本处理 from rdkit import Chem from rdkit.Chem import AllChem, rdFMCS # 读取分子 mol = Chem.MolFromMol2File('molecule.mol2') mol = Chem.AddHs(mol) # 添加氢原子 分子片段连接 RDKit提供了强大的分子片段连接功能: from rdkit.Chem import rdmolops def connect_mols(mol1, mol2, atom1, atom2): # 连接两个分子片段的函数 # atom1和atom2是连接点的原子索引 pass # 参考资源:[RDKit片段连接指南](https://iwatobipen.wordpress.com/2020/10/16/easy-way-to-connect-fragments-rdkit-tips-memo/):https://iwatobipen.wordpress.com/2020/10/16/easy-way-to-connect-fragments-rdkit-tips-memo/ 分子片段处理 # 获取分子片段 from rdkit.Chem.rdmolops import GetMolFrags # 处理虚原子标记片段 # 在RDKit中,虚原子可以用来标记这是一个片段 分子组合 from rdkit.Chem import CombineMols # 组合多个分子 combined_mol = CombineMols(mol1, mol2) 分子可视化和绘制 网格图像生成 from rdkit.Chem import Draw # 生成分子网格图像 注意:目前rdkit.Chem.Draw.MolsToGridImage函数没有直接设置图例字体大小的选项。 高级绘制选项 # 分子绘制选项设置 from rdkit.Chem.Draw import MolDrawing, rdMolDraw2D # 分子绘制选项 # 参考: [RDKit绘制选项文档](https://www.rdkit.org/docs/source/rdkit.Chem.Draw.MolDrawing.html#rdkit.Chem.Draw.MolDrawing.DrawingOptions): https://www.rdkit.org/docs/source/rdkit.Chem.Draw.MolDrawing.html#rdkit.Chem.Draw.MolDrawing.DrawingOptions # 分子2D绘制选项 # 参考: [RDKit 2D绘制选项](https://www.rdkit.org/docs/source/rdkit.Chem.Draw.rdMolDraw2D.html#rdkit.Chem.Draw.rdMolDraw2D.MolDrawOptions): https://www.rdkit.org/docs/source/rdkit.Chem.Draw.rdMolDraw2D.html#rdkit.Chem.Draw.rdMolDraw2D.MolDrawOptions 多分子高亮显示 RDKit高亮显示博客: https://greglandrum.github.io/rdkit-blog/posts/2021-08-07-rgd-and-highlighting.html 注意:DrawMolsToGridImage()不支持多重高亮显示功能。 文件格式和兼容性 mol2文件处理 处理mol2文件时的常见问题: 价态错误处理: 如果遇到:”Explicit valence for atom # 8 N, 4, is greater than permitted” 这通常是因为氮原子的价态设置不正确 分子坐标处理 # 将分子质心移动到原点(0,0,0) def translate_mol_to_origin(mol): # 计算质心并进行平移变换 pass 高级分子处理 分子体积计算 from rdkit.Chem import rdMolDescriptors from rdkit.Chem.AllChem import ComputeMolVolume # 计算分子体积 volume = ComputeMolVolume(mol) RDKit分子体积计算文档: https://www.rdkit.org/docs/source/rdkit.Chem.AllChem.html#rdkit.Chem.AllChem.ComputeMolVolume 分子对齐与匹配 from rdkit.Chem import rdMolAlign # 分子对齐:提供原子映射,使用反向GetSubstructureMatch match = mol.GetSubstructMatches(cmn_core) RDKit分子对齐文档: https://www.rdkit.org/new_docs/source/rdkit.Chem.rdMolAlign.html 最大公共子结构(MCS) # MCS计算 from rdkit.Chem import rdFMCS # 计算最大公共子结构 mcs = rdFMCS.FindMCS([mol1, mol2]) RDKit MCS文档: https://rdkit.org/docs/source/rdkit.Chem.MCS.html 3D MCS应用: RDKit博客3D MCS文章: https://greglandrum.github.io/rdkit-blog/posts/2022-06-23-3d-mcs.html Gaussian计算 环境配置和权限问题 权限问题解决 Gaussian对文件权限要求非常严格: # 运行时如果提示"files in the gaussian directory are world accessible. this must be fixed" find . -type f -exec chmod a+x {} \; # 或者使用 chmod 750 -R * 原因:Gaussian如果发现其可执行文件对所有用户都可访问时就会拒绝运行,这是Gaussian的一个固执特点。 输入文件生成 从mol2文件生成Gaussian输入 # 常见需求:从mol2文件生成包含连接信息的Gaussian输入文件 # 可以使用antechamber进行转换 antechamber -i input.mol2 -fi mol2 -o output.gjf -fo gcrt 连接信息处理 注意:antechamber/G16猜测连接列表时,键序不一定正确,但需要保证合理性。 量子化学计算类型 RESP电荷计算 RESP (Restrained Electrostatic Potential) 电荷是分子动力学中常用的原子电荷: # 使用antechamber计算RESP电荷 antechamber -fi gout -fo ac -i pet.log -o pet.ac -c resp -pf y # 分离运行RESP计算 run resp separately.... AM1-BCC电荷方法 AM1-BCC stands for Austin Model 1 with Bond Charge Correction. 它是计算原子电荷的半经验方法。AM1方法是一种半经验量子化学方法,使用拟合到实验数据的参数集。BCC方法是对AM1电荷的修正,提高其准确性。 电荷约束设置 在antechamber或Multiwfn中手动指定电荷约束: 示例:残基末端的电荷为0 参考:Multiwfn手册 4.7.7.4 Example 4: 天冬氨酸残基的原子电荷评估,包含等价和电荷约束的示例。 高级计算设置 连接信息和拓扑 问题:Gaussian默认不提供连接信息,是否可能获得MD模拟的准确键、角度? 这是一个常见问题,通常需要: 使用其他工具(如antechamber)推断连接 手动指定键连接信息 使用分子编辑器预处理 文件格式处理 mol2格式详解 TRIPOS格式理解 TRIPOS mol2格式示例: @<TRIPOS>MOLECULE lig 45 47 0 0 0 SMALL GASTEIGER 常见格式问题 Gview导出时坐标格式的一致性 不同软件之间mol2格式兼容性 原子类型和电荷信息的处理 antechamber工具深度应用 基本用法 # 从Gaussian输出文件生成mol2 antechamber -i bay.log -fi gout -o bay.mol2 -fo mol2 # 支持的文件格式 # .mc文件支持:antechamber accept .mc file? Python集成 # 在Python中调用antechamber import subprocess def run_antechamber(input_file, output_file, input_format, output_format): cmd = f"antechamber -i {input_file} -fi {input_format} -o {output_file} -fo {output_format}" subprocess.run(cmd, shell=True) 力场参数优化 CGenFF参数优化器 自动优化功能 CGenFF Parameter Optimizer提供自动优化可旋转二面角的功能: 用户指定待优化的二面角 QM数据生成:协调生成量子力学目标数据 参数拟合:使用LSFitPar最小二乘拟合程序 多重度优化: 初始多重度由CGenFF程序分配 自动尝试多重度1, (1,2), (1,2,3), (1,2,3,6) 如果RMSE改善超过阈值(默认10%),选择更好的参数 QM计算集成 首先生成Psi4 QM任务 收集QM二面角扫描数据 拟合力场参数到这些目标数据 实用工具和脚本 Multiwfn应用 # Multiwfn可执行文件权限设置 chmod +x /path/to/Multiwfn_3.8_dev_bin_Linux/Multiwfn ACPYPE工具 结合AmberTools + ACPYPE + Gaussian创建小分子GAFF力场的拓扑文件: 参考:ACPYPE GAFF力场创建指南:https://jerkwin.github.io/2015/12/08/使用AmberTools+ACPYPE+Gaussian创建小分子GAFF力场的拓扑文件/ 在线工具和资源 RESP电荷计算工具 R.E.D. (RESP ESP charge Derive):在线RESP电荷计算程序 虽然界面设计较旧,但功能齐全 更新状态:Last update of the R.E.D. Home Page: June 16th, 2017 文档和教程 RESP电荷计算指南:https://jamesmccarty.github.io/research-wiki/RESP RDKit讨论区:https://sourceforge.net/p/rdkit/mailman/ mol2格式说明:http://chemyang.ccnu.edu.cn/ccb/server/AIMMS/mol2.pdf 常见错误和解决方案 RDKit相关错误 价态问题 reading mol2: Explicit valence for atom # 8 N, 4, is greater than permitted 解决方案: 检查mol2文件中氮原子的键连接 确认原子类型设置正确 必要时手动调整分子结构 导入问题 确保mol2文件格式正确 检查原子坐标和连接表的一致性 注意不同软件生成的mol2文件格式差异 Gaussian相关错误 权限错误 最常见的Gaussian错误之一,严格按照权限设置要求执行: chmod 750 -R gaussian_directory/ 连接猜测问题 Gaussian的连接猜测算法有时不准确 建议使用其他工具预处理分子结构 或手动指定连接信息 工作流程建议 典型的小分子参数化流程 结构优化:Gaussian几何优化 电荷计算:RESP或AM1-BCC电荷 参数生成:antechamber生成力场参数 验证检查:RDKit验证分子结构合理性 MD准备:转换为MD程序所需格式 质量控制检查点 分子几何的合理性 电荷分布的物理意义 力场参数的完整性 与实验数据的一致性 深度学习与化学信息学 DeepChem应用 基础使用 import deepchem as dc # DeepChem是用于药物发现和化学信息学的深度学习库 # 提供分子特征化、模型训练和预测功能 DeepChem是专门为药物发现和化学信息学设计的深度学习库,集成了多种分子表示方法、模型架构和评估指标。 分子可视化扩展工具 Mols2grid网格显示 import mols2grid # 显示和滚动浏览聚类样本 mols2grid.display(molecules) mols2grid提供了交互式的分子网格显示功能,特别适合大量分子的筛选和比较工作。 集成化学信息学工作流 现代化学信息学技术栈 RDKit: 核心分子处理和计算 DeepChem: 深度学习模型开发 Gaussian: 量子化学计算 Mols2grid: 交互式分子可视化 antechamber: 力场参数生成 推荐的集成工作流程 分子预处理: RDKit标准化和验证 特征提取: 结合传统描述符和深度学习特征 量子计算: Gaussian优化和性质计算 模型开发: DeepChem构建预测模型 结果可视化: mols2grid交互式展示 本文基于2023年9-12月和2024年上半年技术讨论记录整理,涵盖计算化学和化学信息学工具使用中的实际问题和解决方案
Techniques
· 2025-10-08
Pytest Deep Dive Tutorial: Beginner-Friendly Guide to Python Testing
Pytest 深度入门教程 (初学者友好版) pytest 是一个功能丰富、易于使用且非常流行的 Python 测试框架。与 Python 内置的 unittest 模块相比,pytest 的语法更简洁、更灵活,并且拥有庞大的插件生态系统,能够极大地提升你的测试效率和体验。 想象一下,你是一位大厨,需要确保每一道菜品都符合标准。测试代码就像是品尝和检验菜品的过程,而 pytest 就是一套能帮你高效完成这个过程的顶级厨具和标准化流程。 为什么选择 Pytest? 简单易学,上手快: 你不需要学习复杂的类结构,直接使用标准的 Python 函数来编写测试。 断言(检查条件是否为真)直接使用 Python 内置的 assert 语句,非常直观。 强大的断言功能: pytest 对 assert 语句进行了智能处理。当断言失败时,它会提供非常详细的上下文信息,告诉你哪里出了错,以及相关变量的当前值,极大地帮助调试。 自动发现测试: 你只需要遵循简单的命名约定,pytest 就能自动找到你的测试文件和测试函数,无需手动注册。 丰富的插件生态系统: 拥有大量开箱即用的插件,例如: pytest-cov: 用于生成测试覆盖率报告。 pytest-xdist: 用于并行执行测试,加快测试速度。 pytest-django, pytest-flask: 用于集成主流Web框架。 还有更多用于报告、Mocking 等功能的插件。 优雅的 Fixtures (测试固件/夹具): 这是 pytest 的核心特性之一。Fixtures 提供了一种模块化、可重用的方式来管理测试的准备工作(setup)和清理工作(teardown)。你可以把它们看作是测试函数运行前需要准备好的“原材料”或“环境”。 灵活的参数化测试 (Parametrization): 可以非常方便地为同一个测试函数提供多组不同的输入数据和预期输出,避免编写大量重复的测试逻辑。 清晰的测试报告: 默认提供简洁明了的测试报告,通过插件还可以生成更详细的HTML报告。 安装 Pytest 安装 pytest 非常简单,只需要使用 pip: pip install pytest 安装完成后,你就可以在你的项目中使用 pytest 了。 你的第一个 Pytest 测试 pytest 通过遵循特定的命名约定来自动发现测试: 测试文件: 通常命名为 test_*.py (例如 test_calculator.py) 或 *_test.py (例如 calculator_test.py)。 测试函数: 在测试文件中,以 test_ 开头的函数会被识别为测试函数 (例如 def test_addition():)。 测试类 (可选): 如果你喜欢将相关的测试组织在类中,类名应以 Test 开头 (例如 class TestCalculator:),类中的测试方法同样以 test_ 开头。pytest 不需要测试类继承任何特定的基类。 让我们创建一个名为 test_example.py 的文件,并编写一个简单的测试: # test_example.py # 这是我们要测试的函数 def inc(x): return x + 1 # 这是我们的第一个测试函数 def test_increment_positive_number(): # "Arrange" (准备) - 定义输入和预期输出 input_value = 3 expected_value = 4 # "Act" (执行) - 调用被测试的函数 result = inc(input_value) # "Assert" (断言) - 检查结果是否符合预期 assert result == expected_value def test_increment_zero(): assert inc(0) == 1 def test_increment_negative_number(): assert inc(-5) == -4 代码解释: 我们定义了一个简单的函数 inc(x),它将输入值加1。 test_increment_positive_number 是一个测试函数。它遵循了“Arrange-Act-Assert”(AAA)模式: Arrange: 设置测试所需的初始条件和输入。 Act: 执行被测试的代码。 Assert: 验证结果是否与预期相符。 我们直接使用 assert 关键字来声明我们的期望。如果 inc(3) 的结果不等于 4,assert 语句会抛出 AssertionError,pytest 会捕获这个错误并将测试标记为失败。 运行你的测试 打开你的终端或命令行工具,导航到包含 test_example.py 文件的目录,然后简单地运行以下命令: pytest 发生了什么? pytest 会从当前目录开始,递归地查找所有符合命名约定的测试文件 (test_*.py 或 *_test.py)。 在找到的测试文件中,它会查找所有符合命名约定的测试函数 (test_*) 或测试类 (Test*) 中的测试方法。 然后,它会逐个执行这些测试。 最后,它会汇总结果并显示出来。 预期输出 (默认模式): ============================= test session starts ============================== platform ... -- Python ... plugins: ... collected 3 items test_example.py ... [100%] ============================== 3 passed in X.XXs =============================== collected 3 items: pytest 找到了3个测试函数。 test_example.py ...: 每个点 (.) 代表一个通过的测试。如果所有测试都通过,你会看到一串点。 3 passed in X.XXs: 总结信息,告诉你有多少测试通过以及花费的时间。 如果某个测试失败了,比如我们故意修改 test_increment_zero: # test_example.py # ... (其他代码不变) ... def test_increment_zero(): assert inc(0) == 2 # 故意写错,应该是 1 再次运行 pytest,输出会变成: ============================= test session starts ============================== platform ... -- Python ... plugins: ... collected 3 items test_example.py .F. [100%] =================================== FAILURES =================================== ___________________________ test_increment_zero ____________________________ def test_increment_zero(): > assert inc(0) == 2 # 故意写错,应该是 1 E assert 1 == 2 E + where 1 = inc(0) test_example.py:14: AssertionError =========================== short test summary info ============================ FAILED test_example.py::test_increment_zero - assert 1 == 2 ========================= 1 failed, 2 passed in X.XXs ========================== 注意看 FAILURES 部分,pytest 非常清晰地指出了: 哪个测试函数失败了 (test_increment_zero)。 失败的 assert 语句是什么 (assert inc(0) == 2)。 断言失败时的具体值比较 (assert 1 == 2),并且它还告诉我们 1 是 inc(0) 的结果。这种详细的错误报告是 pytest 的一大优势。 理解 -v (详细) 和 -q (静默) 参数 pytest 提供了不同的命令行选项来控制输出的详细程度。 pytest (无参数 - 默认模式): 如上所示,对每个通过的测试显示一个点 (.)。 失败的测试显示 F。 如果测试代码本身有错误(不是断言失败,而是比如语法错误或未捕获的异常),会显示 E。 最后会有一个总结,如果存在失败或错误,会有详细的失败信息。 pytest -v (verbose - 详细模式): 这个选项会为每个测试函数显示其完整的名称以及测试结果 (PASSED, FAILED, ERROR)。 当你有很多测试,并且想清楚地看到每个测试的执行状态时,这个模式非常有用。 pytest -v 如果所有测试都通过,输出示例: ============================= test session starts ============================== platform ... -- Python ... plugins: ... collected 3 items test_example.py::test_increment_positive_number PASSED [ 33%] test_example.py::test_increment_zero PASSED [ 66%] test_example.py::test_increment_negative_number PASSED [100%] ============================== 3 passed in X.XXs =============================== pytest -q (quiet - 静默模式): 这个选项会大幅减少输出信息。 如果所有测试都通过,它通常只输出最后的总结行,甚至可能什么都不输出(除了最终的退出码)。 只有在测试失败或出错时,它才会输出相关的错误信息和总结。 这个模式非常适合在持续集成 (CI) 系统中使用,因为你通常只关心是否有问题发生。 pytest -q 如果所有测试都通过,输出示例可能仅仅是: ============================== 3 passed in X.XXs =============================== 或者,如果CI环境配置为在成功时不输出,你可能什么都看不到。 如果你之前运行 pytest -q 没有看到任何关于测试通过的点的输出,那恰恰说明你的所有测试都成功通过了! -q 的设计目标就是在一切顺利时保持安静。 何时使用哪个参数? 日常开发,快速检查:pytest 想看每个测试的名称和状态,或者调试时:pytest -v 在自动化脚本或CI环境中,只关心失败:pytest -q 使用 assert 进行强大的断言 pytest 最棒的一点就是它允许你直接使用 Python 内置的 assert 语句。当 assert 后面的条件为 False 时,会引发 AssertionError。pytest 会捕获这个错误,将测试标记为失败,并提供非常丰富的调试信息,包括表达式中各个部分的值。 让我们看更多断言的例子。创建一个新文件 test_assertions.py: # test_assertions.py import pytest # 需要导入 pytest 来使用 pytest.raises # 要测试的函数 def get_user_info(user_id): if user_id == 1: return {"name": "Alice", "age": 30, "active": True} elif user_id == 2: return {"name": "Bob", "age": 24, "active": False} else: return None def divide(a, b): if b == 0: raise ValueError("Cannot divide by zero") # 注意:这里我们抛出 ValueError return a / b # 测试函数 def test_user_alice(): alice = get_user_info(1) assert alice is not None assert alice["name"] == "Alice" assert alice["age"] > 25 assert alice["active"] is True # 明确检查布尔值 def test_user_bob_inactive(): bob = get_user_info(2) assert bob["name"].startswith("B") assert not bob["active"] # 另一种检查 False 的方式 assert "email" not in bob # 检查字典中是否不包含某个键 def test_unknown_user(): unknown = get_user_info(99) assert unknown is None def test_division_normal(): assert divide(10, 2) == 5.0 assert divide(7, 2) == 3.5 def test_division_by_zero_custom_error(): # 测试函数是否按预期抛出了特定的异常 # pytest.raises 作为一个上下文管理器使用 with pytest.raises(ValueError) as excinfo: # 捕获 ValueError divide(10, 0) # 可选:检查异常信息是否符合预期 assert "Cannot divide by zero" in str(excinfo.value) def test_list_operations(): my_list = [10, 20, 30, 40] assert 20 in my_list assert 50 not in my_list assert len(my_list) == 4 # Pytest 的断言内省对于比较序列非常有用 # 如果下面这个断言失败了: assert my_list == [10, 20, 35, 40] # Pytest 会告诉你具体哪个元素不同 assert my_list == [10, 20, 30, 40] def test_string_properties(): text = "Pytest is awesome!" assert "awesome" in text assert text.lower() == "pytest is awesome!" assert text.endswith("!") assert len(text.split()) == 3 运行这些测试: pytest test_assertions.py -v 关键点: 丰富的比较信息: 如果 assert alice["name"] == "Bob" 失败了 (因为实际上是 “Alice”),pytest 会告诉你 assert "Alice" == "Bob",让你清楚地看到实际值和期望值的差异。 测试异常 (pytest.raises): 当你期望某段代码抛出特定类型的异常时,使用 pytest.raises。它会捕获预期的异常,如果代码没有抛出该异常,或者抛出了不同类型的异常,测试就会失败。excinfo 对象包含了关于捕获到的异常的详细信息。 涵盖多种数据类型: 你可以用 assert 来检查数字、字符串、列表、字典、布尔值等几乎所有 Python 对象。 参数化测试 (@pytest.mark.parametrize) 当你需要用不同的输入和期望输出来测试同一个函数逻辑时,参数化测试非常有用。它可以避免你编写大量结构相似的测试函数。 你已经在你的 test_single_and_batch 测试中使用了它,这是一个很好的实践! 让我们创建一个 test_parametrize_examples.py 文件: # test_parametrize_examples.py import pytest # 要测试的函数 defis_palindrome(text): if not isinstance(text, str): raise TypeError("Input must be a string") return text.lower() == text.lower()[::-1] # 使用 parametrize @pytest.mark.parametrize("test_input, expected_output", [ ("madam", True), ("racecar", True), ("hello", False), ("Aibohphobia", True), # 测试大小写不敏感 ("", True), # 测试空字符串 (" ", True), # 测试单个空格 ("No lemon, no melon.", False) # 包含标点和空格,按当前函数逻辑会失败 ]) def test_is_palindrome_various_inputs(test_input, expected_output): assertis_palindrome(test_input) == expected_output # 另一个例子:测试数据类型检查 @pytest.mark.parametrize("invalid_input", [ 123, ["list"], None, {"a": 1} ]) def test_is_palindrome_invalid_type(invalid_input): with pytest.raises(TypeError) as excinfo: is_palindrome(invalid_input) assert "Input must be a string" in str(excinfo.value) # 你也可以给每个参数组合起一个ID,方便在报告中识别 @pytest.mark.parametrize( "a, b, expected_sum", [ pytest.param(1, 2, 3, id="positive_nums"), pytest.param(-1, -2, -3, id="negative_nums"), pytest.param(-1, 1, 0, id="mixed_nums"), pytest.param(0, 0, 0, id="zeros") ] ) def test_addition(a, b, expected_sum): assert a + b == expected_sum 运行: pytest test_parametrize_examples.py -v 你会看到 test_is_palindrome_various_inputs 为每一组参数都运行了一次。如果其中一组失败,报告会明确指出是哪一组参数导致了失败。test_addition 的输出会使用你提供的 id 来标识每个测试用例。 参数化的好处: 代码简洁: 避免了为每个场景编写单独的测试函数。 可读性高: 测试数据和预期结果清晰地组织在一起。 易于扩展: 添加新的测试场景只需要在参数列表中增加一行。 覆盖更全: 方便测试各种边界条件和特殊情况。 Fixtures (测试固件/夹具) - 优雅的测试准备与清理 Fixtures 是 pytest 中一个非常强大和核心的概念。它们用于: 提供测试所需的上下文或数据: 比如一个数据库连接、一个临时文件、一个已登录的用户对象等。 管理测试的准备 (setup) 和清理 (teardown) 过程: 确保测试在一致的环境中运行,并在测试结束后释放资源。 你可以把 fixture 想象成戏剧表演中的“道具”或“场景布置”。每个需要特定道具的“场景”(测试函数)都可以声明它需要哪些道具,pytest 会在场景开始前准备好这些道具,并在场景结束后清理它们。 定义 Fixture: Fixture 本身也是一个 Python 函数,使用 @pytest.fixture 装饰器来标记。 使用 Fixture: 测试函数如果需要某个 fixture,只需将其名称作为参数声明即可。pytest 会自动查找并执行对应的 fixture 函数,并将其返回值(如果有的话)传递给测试函数。 1. 基础 Fixture 示例 让我们创建一个 test_fixtures_basic.py 文件: # test_fixtures_basic.py import pytest import tempfile # 用于创建临时文件/目录 import os import shutil # 用于删除目录 # 定义一个 fixture,它会创建一个简单的字典数据 @pytest.fixture def sample_user_data(): print("\n(Fixture: Creating sample_user_data...)") # 方便观察fixture何时执行 data = {"username": "testuser", "email": "test@example.com", "is_active": True} return data # 测试函数使用这个 fixture def test_user_username(sample_user_data): print("\n(Test: Running test_user_username...)") assert sample_user_data["username"] == "testuser" def test_user_is_active(sample_user_data): print("\n(Test: Running test_user_is_active...)") assert sample_user_data["is_active"] is True # 另一个 fixture,演示 setup 和 teardown (使用 yield) @pytest.fixture def managed_tmp_dir(): dir_name = tempfile.mkdtemp(prefix="pytest_managed_") # Setup: 创建临时目录 print(f"\n(Fixture: Created temp directory: {dir_name})") yield dir_name # fixture 的值在这里提供给测试函数 # Teardown: 测试函数执行完毕后,这里的代码会执行 print(f"\n(Fixture: Cleaning up temp directory: {dir_name})") shutil.rmtree(dir_name) # 清理临时目录 def test_create_file_in_managed_dir(managed_tmp_dir): print(f"\n(Test: Running test_create_file_in_managed_dir with {managed_tmp_dir})") file_path = os.path.join(managed_tmp_dir, "test_file.txt") with open(file_path, "w") as f: f.write("Hello from fixture test!") assert os.path.exists(file_path) 运行 pytest -v -s test_fixtures_basic.py ( -s 选项可以让你看到 print 语句的输出,方便观察 fixture 的执行流程)。 你会注意到: sample_user_data fixture 在每个需要它的测试函数(test_user_username 和 test_user_is_active)运行之前都会被调用一次。 managed_tmp_dir fixture 在 test_create_file_in_managed_dir 运行前创建了目录,测试结束后该目录被清理。yield 语句是实现这种 setup/teardown 模式的关键。在 yield 之前是 setup 代码,之后是 teardown 代码。 2. Fixture 作用域 (Scope) Fixture 可以有不同的作用域,决定了 fixture 函数执行的频率以及其返回值的生命周期: function (默认): 每个测试函数执行一次。这是最常见的,确保每个测试都有一个干净、独立的 fixture 实例。 class: 每个测试类执行一次。该类中所有测试方法共享同一个 fixture 实例。 module: 每个模块(测试文件)执行一次。该模块中所有测试函数/方法共享同一个 fixture 实例。 session: 整个测试会话(即一次 pytest 运行)执行一次。所有测试共享同一个 fixture 实例。这对于昂贵的 setup 操作(如启动一个外部服务)非常有用。 通过在 @pytest.fixture 装饰器中指定 scope 参数来设置作用域: # test_fixture_scopes.py import pytest # Session-scoped fixture: 在整个测试会话中只执行一次 @pytest.fixture(scope="session") def db_connection(): print("\n(SESSION Fixture: Connecting to database...)") connection = "fake_db_connection_string" # 模拟数据库连接 yield connection print("\n(SESSION Fixture: Closing database connection...)") # Module-scoped fixture: 在这个模块中只执行一次 @pytest.fixture(scope="module") def module_resource(db_connection): # Fixtures 可以依赖其他 fixtures print(f"\n(MODULE Fixture: Setting up module resource using {db_connection}...)") resource = {"id": "module_res_123", "db": db_connection} yield resource print("\n(MODULE Fixture: Tearing down module resource...)") class TestUserOperations: # Class-scoped fixture: 对这个类只执行一次 @pytest.fixture(scope="class") def user_service(self, module_resource): # 注意类方法中的 fixture 需要 self print(f"\n(CLASS Fixture: Initializing UserSerice with {module_resource['id']}...)") service = f"UserService_instance_for_{module_resource['id']}" yield service print("\n(CLASS Fixture: Shutting down UserService...)") # Function-scoped fixture (默认) @pytest.fixture def new_user_payload(self): print("\n(FUNCTION Fixture: Creating new_user_payload...)") return {"username": "temp_user", "role": "guest"} def test_get_user(self, user_service, db_connection): # 使用 class 和 session fixture print(f"\n(Test: test_get_user using {user_service} and {db_connection})") assert user_service is not None assert "fake_db" in db_connection def test_create_user(self, user_service, new_user_payload, module_resource): # 使用 class, function, module fixture print(f"\n(Test: test_create_user using {user_service}, payload: {new_user_payload}, module_res: {module_resource['id']})") assert new_user_payload["username"] == "temp_user" assert module_resource is not None def test_another_module_level_test(module_resource, db_connection): print(f"\n(Test: test_another_module_level_test using {module_resource['id']} and {db_connection})") assert "module_res" in module_resource["id"] 运行 pytest -v -s test_fixture_scopes.py。仔细观察 print 语句的输出顺序和次数,你就能理解不同作用域的 fixture 是如何工作的。 选择合适的作用域很重要: 如果 fixture 的创建和销毁成本很高,或者你希望在多个测试之间共享状态(要小心!),可以使用更广的作用域(class, module, session)。 为了测试的独立性和避免副作用,function 作用域通常是首选。 3. 内置 Fixtures pytest 提供了一些非常有用的内置 fixtures,例如: tmp_path (function scope): 提供一个临时的目录路径 (pathlib.Path 对象),测试结束后会自动清理。 tmp_path_factory (session scope): 一个工厂 fixture,可以用来创建多个临时目录。 capsys, capfd: 用于捕获测试期间打印到 stdout/stderr 的内容。 monkeypatch: 用于安全地修改或替换模块、类或对象的属性,测试结束后自动恢复。 request: 一个特殊的 fixture,提供了关于当前正在执行的测试请求的信息。 你在之前的教程中已经用到了 tmp_path: # test_fixture.py (部分回顾) @pytest.fixture def tmp_file(tmp_path): # tmp_path 是内置 fixture file_path = tmp_path / "my_temp_file.txt" file_path.write_text("test content") return file_path 4. conftest.py: 共享 Fixtures 如果你的多个测试文件都需要使用相同的 fixtures,你可以将它们定义在一个名为 conftest.py 的文件中。pytest 会自动发现并加载 conftest.py 文件中的 fixtures,使其在同一目录及其子目录下的所有测试文件中可用,无需显式导入。 项目结构示例: my_project/ ├── conftest.py # 共享的 fixtures 在这里定义 ├── package_a/ │ └── test_module_a.py └── package_b/ └── test_module_b.py ```conftest.py` 中的内容: ```python # my_project/conftest.py import pytest @pytest.fixture(scope="session") def global_config(): print("\n(CONFTEST: Loading global config...)") return {"api_url": "http://example.com/api", "timeout": 30} 在 test_module_a.py 中可以直接使用 global_config: # my_project/package_a/test_module_a.py def test_api_url(global_config): # 无需导入,可以直接使用 assert "example.com" in global_config["api_url"] ```conftest.py` 是组织和共享 fixtures 的标准方式,能让你的测试代码更整洁。 ## 使用标记 (Markers) 管理测试 `pytest` 允许你使用“标记 (markers)”来给测试函数或类添加元数据。这些标记可以用于: * 跳过某些测试。 * 在特定条件下跳过测试。 * 将测试标记为预期失败 (xfail)。 * 对测试进行分类,方便选择性地运行。 ### 1. 内置标记 * **`@pytest.mark.skip(reason="...")`**: 无条件跳过该测试。 * **`@pytest.mark.skipif(condition, reason="...")`**: 当 `condition` 为真时跳过该测试。 * **`@pytest.mark.xfail(condition, reason="...", strict=False)`**: 标记测试为“预期失败”。如果测试实际通过了(而你标记为 xfail),默认情况下会报告为 `XPASS`。如果测试如预期般失败了,会报告为 `XFAIL`。如果设置 `strict=True`,那么 `XPASS` 会被视为测试失败。这对于标记那些已知有 bug 但暂时不修复的测试很有用。 * **`@pytest.mark.parametrize(...)`**: 我们已经学习过了,用于参数化测试。 ```python # test_markers.py import pytest import sys def get_python_version(): return sys.version_info @pytest.mark.skip(reason="这个功能尚未实现") def test_new_feature(): assert False IS_WINDOWS = sys.platform == "win32" @pytest.mark.skipif(IS_WINDOWS, reason="此测试仅在非 Windows 系统上运行") def test_linux_specific_path(): path = "/usr/local/bin" assert path.startswith("/") @pytest.mark.skipif(get_python_version() < (3, 8), reason="需要 Python 3.8 或更高版本") def test_feature_for_python38_plus(): # 一些只在 Python 3.8+ 中可用的特性 assert True @pytest.mark.xfail(reason="已知bug #123,除数为零") def test_division_bug(): assert 1 / 0 == 1 # 这会抛出 ZeroDivisionError @pytest.mark.xfail(get_python_version() < (3, 10), reason="此功能在旧版Python中可能表现不同") def test_potentially_flaky_on_old_python(): # 假设这个测试在 Python < 3.10 时可能通过也可能失败 if get_python_version() < (3, 10): assert 1 == 1 # 在旧版 Python 中,我们预期它可能失败 (xfail) else: assert 1 == 1 # 在新版 Python 中,我们预期它通过 2. 自定义标记与运行特定标记的测试 你可以定义自己的标记,以便对测试进行逻辑分组。在 pytest.ini 或 pyproject.toml 文件中注册自定义标记是个好习惯,以避免拼写错误和警告。 pytest.ini 示例: [pytest] markers = slow: 标记运行缓慢的测试 smoke: 标记为冒烟测试,用于快速检查核心功能 integration: 标记为集成测试 在测试中使用自定义标记: # test_custom_markers.py import pytest import time @pytest.mark.slow def test_very_slow_operation(): time.sleep(2) # 模拟一个耗时操作 assert True @pytest.mark.smoke def test_quick_check(): assert 1 + 1 == 2 @pytest.mark.integration @pytest.mark.smoke # 一个测试可以有多个标记 def test_api_login(): # 模拟 API 登录 assert True 运行特定标记的测试: 使用 -m 命令行选项: pytest -m smoke # 只运行标记为 smoke 的测试 pytest -m "not slow" # 运行所有未标记为 slow 的测试 pytest -m "smoke and integration" # 运行同时标记为 smoke 和 integration 的测试 pytest -m "smoke or slow" # 运行标记为 smoke 或 slow 的测试 组织测试:测试类 虽然 pytest 不需要你把测试写在类里,但对于组织一组相关的测试,使用类是一个不错的选择。 类名必须以 Test 开头。 类中的测试方法名必须以 test_ 开头。 不需要继承任何特定的基类 (如 unittest.TestCase)。 # test_calculator_class.py class Calculator: def add(self, a, b): return a + b def subtract(self, a, b): return a - b def multiply(self, a, b): return a * b def divide(self, a, b): if b == 0: raise ValueError("Cannot divide by zero") return a / b class TestCalculator: # 你可以在类级别使用 fixture,它会对该类的所有测试方法生效 # (如果 fixture scope 是 'class' 或更广) # 例如,可以在这里创建一个 Calculator 实例供所有测试使用 def test_addition(self): # 注意方法需要 self 参数 calc = Calculator() assert calc.add(2, 3) == 5 assert calc.add(-1, 1) == 0 def test_subtraction(self): calc = Calculator() assert calc.subtract(5, 3) == 2 # ... 其他测试方法 ... 配置文件 (pytest.ini 或 pyproject.toml) 你可以通过在项目根目录创建 pytest.ini 文件或在 pyproject.toml 中添加 [tool.pytest.ini_options] 部分,来自定义 pytest 的行为。 pytest.ini 示例: [pytest] # 改变测试文件的发现模式 python_files = test_*.py check_*.py example_*.py # 改变测试函数/方法的发现模式 python_functions = test_* check_* example_* # 改变测试类的发现模式 python_classes = Test* Check* Example* # 默认添加的命令行选项 addopts = -v --cov=. --cov-report=html # 注册自定义标记 (避免警告) markers = slow: marks tests as slow to run serial: marks tests that cannot be run in parallel # 忽略某些目录 norecursedirs = .git venv build *.egg-info 这只是冰山一角,pytest 的配置选项非常丰富。 总结与后续学习 恭喜你!通过这个扩展教程,你已经掌握了 pytest 的许多核心概念和实用技巧: 编写和运行基础测试。 理解不同的输出模式 (-v, -q)。 使用强大的 assert 语句进行断言和异常测试。 通过 @pytest.mark.parametrize 实现参数化测试,提高测试覆盖率和代码复用。 掌握了 Fixture 的核心用法,包括定义、使用、作用域 (function, class, module, session)、带 yield 的 setup/teardown 模式,以及如何通过 conftest.py 共享 fixtures。 了解了如何使用标记 (@pytest.mark.*) 来管理和选择性地运行测试。 知道了如何将测试组织在类中。 对 pytest 的配置文件有了初步认识。 接下来你可以探索: 更高级的 Fixture 用法: 如 autouse fixtures,fixture 的参数化,使用 fixture 返回工厂函数等。 插件的使用: pytest-cov: 测试覆盖率。 pytest-xdist: 并行测试。 pytest-mock: 方便地使用 mocking。 针对你使用的框架(如 Django, Flask, FastAPI)的 pytest 插件。 生成 HTML 测试报告: 使用 pytest-html 插件。 pytest 官方文档: 这是最权威和最全面的学习资源 (https://docs.pytest.org/)。 编写测试是保证代码质量、提升开发信心的关键环节。pytest 以其简洁和强大,让编写测试不再是一件苦差事,反而可以成为一种乐趣。希望这篇教程能帮助你轻松入门并爱上 pytest!
Techniques
· 2025-10-08
【笔记整理|2024年上半年】Python开发环境与工程化笔记整理
【笔记整理|2024年上半年】Python开发环境与工程化笔记整理 本文汇总了Python开发环境配置、性能优化、Web开发和工程化实践的技术要点,为高效开发提供全面指导。 Conda环境管理 环境配置 初始化设置 # Conda初始化脚本 __conda_setup="$('/home/user/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" eval "$__conda_setup" if [ -f "/home/user/miniconda3/etc/profile.d/conda.sh" ]; then . "/home/user/miniconda3/etc/profile.d/conda.sh" else export PATH="$PATH:/home/user/miniconda3/bin" fi unset __conda_setup 环境迁移和重建 从旧miniconda迁移到新anaconda时的常见问题: InvalidArchiveError错误: # 清理conda缓存解决依赖问题 conda clean -a 包冲突解决策略: # 例如:acpype依赖AmberTools但Amber不包含acpype # 通过conda安装会获取另一个ambertools # 解决方案:在base环境中使用pip安装 pip install acpype 配置文件设置 conda config --file .condarc --add pkgs_dirs 环境变量配置 # Python环境路径示例 previous_path = "/home/user/anaconda3/envs/pmx/lib/python3.10/site-packages/pmx/data/mutff" # Boost库路径示例(用于编译) boost_path = "/home/user/anaconda3/envs/AMBER22/lib/cmake/Boost-1.78.0/BoostConfig.cmake" 包管理最佳实践 PyPI镜像配置 # 临时使用镜像 pip install -i https://mirrors.zju.edu.cn/pypi/web/simple some-package # 永久配置镜像 pip config set global.index-url https://mirrors.zju.edu.cn/pypi/web/simple 包强制重装 pip install --upgrade --force-reinstall <package> Web开发与爬虫技术 Selenium自动化 Selenium基础设置 from selenium import webdriver # 创建WebDriver实例 driver = webdriver.Chrome() 连接错误处理 urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='localhost', port=17823): Max retries exceeded with url: /session/xxx/url 这种错误通常是由于目标计算机积极拒绝连接导致的。 页面滚动与交互 页面滚动实现 # 方法1:JavaScript执行滚动 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 方法2:发送按键模拟用户滚动 from selenium.webdriver.common.keys import Keys driver.find_element_by_tag_name('body').send_keys(Keys.PAGE_DOWN) 元素交互异常 ElementNotInteractableException 此异常表示要交互的元素不在允许交互的状态。可能原因: 元素被隐藏 元素被其他元素覆盖 元素尚未加载完成 静态vs动态内容抓取 静态网页数据抓取 可以使用requests库结合BeautifulSoup来检索静态网页数据。但如果目标网页使用JavaScript动态加载内容,requests可能无法获取完整的页面内容,这种情况下Selenium更适合。 动态加载内容识别 如果div元素通过JavaScript动态加载,使用requests库可能无法获取到这些内容,因为requests只能获取初始的静态HTML,不会执行JavaScript。 工具选择建议 Beautiful Soup:适合解析静态HTML/XML内容,速度更快 Selenium:主要用于动态网页交互和浏览器自动化 Cython性能优化 Cython编译与使用 Cython编译命令 python setup.py build_ext Cython使用建议 可以考虑使用Cython优化一些简单的Python项目。但在非常复杂的场景下,某些语法特性不支持,可能会有绕不过去的坑。 跨平台编译 Windows和Linux需要分别执行编译,然后将编译结果拷贝到目标环境。 数据处理与文件操作 字符串处理技巧 bytes字符串替换 # 在bytes字符串中替换子串 byte_string = byte_string.replace(b"<br/>", b"\n\n") 数字字符串判断 s1 = "12345" # 使用内置方法判断字符串是否为数字 s1.isdigit() # 判断是否为数字 s1.isnumeric() # 判断是否为数值 CSV文件处理 CSV文件写入 import csv # 使用Python标准库csv模块写入CSV文件 with open('output.csv', 'w', newline='') as csvfile: writer = csv.writer(csvfile) writer.writerow(['列1', '列2', '列3']) writer.writerow(['数据1', '数据2', '数据3']) 文件移动操作 Python文件移动教程:https://www.learndatasci.com/solutions/python-move-file/ Python语言特性 条件表达式 Python没有直接的问号语句(如C语言中的 condition ? expression1 : expression2),但有等价的条件表达式 result = value1 if condition else value2 # 这等价于其他语言中的三元条件运算符 外部程序调用 import subprocess # 在Python中调用外部程序(如antechamber) def call_antechamber(input_file, output_file): cmd = f"antechamber -i {input_file} -o {output_file}" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) return result 退出函数使用 exit函数错误 # 错误:NameError: name 'exit' is not defined exit() # 正确:需要导入sys模块 import sys sys.exit() 作用域问题 仅导入sys模块不足以使exit进入全局作用域,需要明确使用sys.exit()。 JSON数据处理 import json # 加载JSON数据的标准方法 with open('data.json', 'r') as f: data = json.load(f) 环境配置优化 PATH环境变量清理 # 清理重复的PATH条目 export PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!($0 in a) {a[$0]; print}' | sed 's/:$//') 子进程配置 # subprocess.Popen默认使用/bin/sh # 若要使用bash需要设置executable参数 subprocess.Popen(..., executable='/bin/bash') Python subprocess使用bash:https://www.saltycrane.com/blog/2011/04/how-use-bash-shell-python-subprocess-instead-binsh/ 代理配置 # 设置HTTP代理 export http_proxy="http://127.0.0.1:7890" 开发工具集成 Python外部程序调用 import subprocess # 调用外部程序的标准方法 def run_external_command(command): result = subprocess.run(command, shell=True, capture_output=True, text=True) return result.stdout, result.stderr 包管理集成 使用subprocess调用系统包管理器: # 调用antechamber等外部工具 def call_antechamber(input_file, output_file): cmd = f"antechamber -i {input_file} -o {output_file}" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) return result PyCharm环境问题: PyCharm本身是一个代码编辑器(IDE),而不是一个网页浏览器。所以它不能像Chrome或Edge那样直接”打开”并渲染localhost:8501的页面内容。建议端口转发。 相关学习资源 Python打包 科学Python打包指南:https://learn.scientific-python.org/development/guides/packaging-simple/ 故障排除与最佳实践 常见错误模式 环境冲突:不同conda环境中包版本不兼容 连接错误:Web爬虫中的网络连接问题 编译问题:Cython跨平台编译差异 字符编码:bytes和str处理不当 调试建议 隔离测试环境冲突 使用虚拟环境避免依赖污染 记录完整的编译配置 注意跨平台兼容性问题 开发环境检查清单 Python版本:确保版本兼容性 依赖管理:使用requirements.txt或environment.yml 虚拟环境:为每个项目创建独立环境 代码质量:使用linter和formatter工具 性能监控:定期进行性能分析 本文基于2023年9月至2024年上半年的开发实践整理,涵盖Python工程化和开发环境配置的实用技术要点
Techniques
· 2025-10-08
NVIDIA & CUDA 环境综合诊断命令集合 (简洁版)
好的,遵照您的要求,我们对推文进行最后的更新和完善。 更新点1:简化网络连接步骤,直接提示在Live USB图形界面中联网。 更新点2:增加关于 apt install cuda 的补充说明,解释它与驱动安装的关系。 更新点3:在文末附上您提供的官方参考链接。 更新点4 (新增):增加一个全新的章节,详细复盘和讲解我们是如何根据报错信息一步步调试加密分区挂载问题的。 Linux系统「急诊室」:一次NVIDIA驱动引发的“引导风暴”终极复盘 写在前面 这是一篇写给Linux用户,尤其是Pop!_OS、Ubuntu等发行版使用者的深度故障排除指南。它源于一次真实的、由NVIDIA驱动安装中断引发的、持续数天的系统“急救”经历。我们将从最初的“无法启动”开始,层层剥茧,深入探索UEFI引导、LUKS全盘加密、LVM逻辑卷管理、initramfs启动机制以及 systemd-boot引导加载程序的每一个细节。 本文的目标不仅是提供解决方案,更是希望通过复盘每一步的报错、诊断和思考过程,帮助您建立一套处理Linux复杂引导问题的系统性思维。 第一幕:风暴之始 - 系统崩溃与初步诊断 故事始于一次常规的CUDA安装。在通过NVIDIA官网教程添加apt源并安装CUDA的过程中,系统意外中断。重启后,熟悉的图形界面消失,我们被抛入了冰冷的“紧急模式” (emergency mode)。 症状1:无尽的紧急模式循环 系统提示 You are in emergency mode,并建议运行日志命令。但任何修复尝试,如 apt upgrade,都会在失败后让系统重新陷入这个模式。 症状2:明确的引导错误 日志中最核心的错误指向了引导分区: kernelstub: ERROR: Could not find a block device for the partition NoBlockDevError: Couldn't find the block device for /boot/efi 解读:kernelstub (Pop!_OS的引导管理工具) 无法找到EFI系统分区(ESP)。这是引导流程中的第一处“骨折”。 如何识别我的分区? 在进行任何修复前,首先要做的就是“知己知彼”,了解自己硬盘的分区结构。在紧急模式或Live USB的终端中,可以使用 lsblk -f 或 sudo parted -ls 命令。 EFI分区 (/boot/efi): 寻找一个大小在 500MB 到 1GB 左右、文件系统类型为 vfat (FAT32) 的分区。在 parted 的输出中,它通常带有 boot, esp 标记。在我们的案例中,它是 /dev/nvme0n1p1。 加密的根分区: 这通常是硬盘上最大的那个分区。在 lsblk -f 的输出中,它的文件系统类型会显示为 crypto_LUKS。在我们的案例中,它是 /dev/nvme0n1p3。 恢复分区: Pop!_OS特有的分区,大小通常为4GB左右,文件系统也是 vfat,parted 输出的标签为 recovery。在我们的案例中,它是 /dev/nvme0n1p2。 第二幕:急救现场 - initramfs 的“瘫痪” 明确分区后,我们尝试在紧急模式下手动挂载EFI分区,但遭遇了更深层的失败。 FAT-fs (nvme0n1p1): IO charset iso8859-1 not found 这个错误说明,紧急模式这个微型系统自身已损坏,缺少了读写EFI分区所必需的基础内核模块。这意味着无法在紧急模式内部完成修复。 有时,系统会直接进入一个功能更孱弱的 (initramfs) 命令行,并抛出致命错误: ALERT! UUID=... does not exist. Dropping to a shell! 这同样印证了 initramfs 镜像已损坏,它内部的引导脚本找不到正确的根分区地址,导致引导过程彻底中断。 核心病因:所有这些症状都指向了同一个罪魁祸首——一次不完整的NVIDIA驱动/CUDA安装,生成了一个残缺的initramfs启动镜像。 第三幕:侦探工作 - 调试复杂的加密分区 在进入最终修复流程前,一个关键的步骤是在 Live USB 环境中成功挂载主系统分区。这个过程本身就是一次精彩的“侦探工作”,我们通过解读错误信息,层层揭开了硬盘的“加密-LVM”复合结构。 第一次尝试:直接挂载 我们首先尝试了最直接的 mount 命令: sudo mount /dev/nvme0n1p3 /mnt 随即遭遇了第一个线索: mount: /mnt: unknown filesystem type 'crypto_LUKS'. 线索解读:系统明确告诉我们,/dev/nvme0n1p3 不是一个可以直接挂载的文件系统,而是一个 crypto_LUKS 加密卷。就像一个上了锁的保险箱,我们不能直接打开,必须先用钥匙解锁。 第二次尝试:解锁加密层 根据线索,我们使用正确的“钥匙”——cryptsetup 工具来解锁: sudo cryptsetup luksOpen /dev/nvme0n1p3 unlocked_root 输入密码后,我们满怀信心地再次尝试挂载新出现的虚拟设备 /dev/mapper/unlocked_root,却得到了第二个线索: mount: /mnt: unknown filesystem type 'LVM2_member'. 线索解读:这个错误再次揭示了更深一层的结构。解锁后的设备依然不是最终的文件系统,而是一个 LVM2_member (LVM物理卷)。这说明“保险箱”里装的不是直接可用的文件,而是另一个“文件柜系统”(LVM)。 最终方案:激活LVM并挂载 有了这个线索,我们知道必须先让系统识别并激活这个“文件柜”,才能拿到最终的文件。 # 激活LVM逻辑卷 sudo vgchange -ay # 挂载LVM中的根分区逻辑卷 sudo mount /dev/mapper/data-root /mnt 这一次,挂载终于成功。通过像侦探一样跟随错误信息的指引,我们成功地手动完成了“解锁保险箱 -> 激活文件柜 -> 取出文件”的整个流程。 第四幕:终极救援 - Live USB “无菌手术” 既然内部修复行通,我们就需要一个功能完备的外部“医疗队”——Live USB。 4.1 准备“手术工具” 在另一台电脑上,下载您当前Linux发行版的ISO镜像。 使用 BalenaEtcher 等工具,将ISO镜像制作成一个可启动的U盘。 将U盘插入故障电脑,开机时进入BIOS/UEFI菜单,选择从U盘启动。 在启动选项中,选择 “Try Pop!_OS” 或 “Try Ubuntu”,进入临时的试用系统。 进入桌面后,首先连接到您的 Wi-Fi 或有线网络,确保网络通畅。 4.2 进入“无菌操作区”(Chroot 环境) 进入Live USB的桌面后,打开一个终端,我们将通过一系列命令,进入到您硬盘上那个“生病”的系统中。 解锁LUKS加密卷 (使用Pop!_OS默认名称 cryptdata): sudo cryptsetup luksOpen /dev/nvme0n1p3 cryptdata 激活LVM逻辑卷: sudo vgchange -ay 挂载系统分区: sudo mount /dev/mapper/data-root /mnt sudo mount /dev/nvme0n1p1 /mnt/boot/efi 绑定系统目录并进入Chroot: for i in dev dev/pts proc sys run; do sudo mount -B /$i /mnt/$i; done sudo chroot /mnt 执行成功后,您终端的提示符会改变。现在,您下达的所有命令都将直接作用于您硬盘上的系统。 4.3 “清创”与“移植”:修复核心问题 在 chroot 环境中,我们将进行一次彻底的“外科手术”。 彻底清除病灶(清除所有NVIDIA软件包): apt-get purge --auto-remove -y '*nvidia*' '*cuda*' 移植“健康器官”(安装新驱动): # 查找最适合您硬件的推荐驱动 ubuntu-drivers devices # 根据上一步的推荐结果,安装驱动(请将 535 替换为您看到的推荐版本) apt install nvidia-driver-535 生成全新的“免疫系统”(重建 initramfs): 这是最关键的一步。它会把刚刚干净安装的NVIDIA驱动和所有正确的配置打包进一个新的启动环境中。 update-initramfs -u -k all 4.4 “唤醒病人”:收尾并重启 退出 chroot 环境: exit 重新安装引导加载程序 (根据官方指南的最后一步): sudo bootctl --path=/mnt/boot/efi install 重启电脑: sudo reboot 在电脑重启时,请务必拔掉您的 USB U盘。 第五幕:疑难杂症处理(Q&A) 问:chroot 中 update-initramfs 报错 Failed to retrieve NVRAM data? 答:正常现象,chroot 环境无法访问主板固件。可以临时将 /etc/initramfs/post-update.d/zz-kernelstub 脚本移走,运行完命令后再移回。 问:chroot 中 nvidia-smi 报错 Driver/library version mismatch? 答:正常现象。chroot 共享的是 Live USB 的内核,与您主系统的驱动程序版本不匹配是必然的。判断驱动是否安装成功,应以 apt 和 update-initramfs 命令是否报错为准。 问:修复后重启默认进入了 recovery 模式? 答:说明主系统引导项已修复,但默认顺序不对。可以在 Recovery 环境中 sudo mount /dev/nvme0n1p1 /boot/efi,然后 sudo nano /boot/efi/loader/loader.conf,手动将 default 行改为 default Pop_OS-current.conf。 补充说明:关于CUDA安装和驱动选择 问:我可以直接 apt install cuda -y 吗?它会自动安装驱动吗? 答:可以,这通常是一个更便捷的选择。 apt install cuda 或 apt install cuda-toolkit 在安装 CUDA 工具包时,会自动将一个经过NVIDIA官方测试、兼容该CUDA版本的专有驱动作为依赖项一并安装。 这意味着您不需要在安装CUDA后再手动 apt install nvidia-driver-XXX。一步 apt install cuda 即可同时搞定工具包和兼容的专有驱动。 在上面的修复流程中,您可以在 4.3节的第2步,将 ubuntu-drivers devices 和 apt install nvidia-driver-XXX 两条命令,直接替换为 apt install cuda -y。后续步骤不变。 结语 如果一切顺利,您将会看到熟悉的图形化解密界面,输入密码后,久违的桌面就会重新出现。这次看似复杂的修复过程,揭示了现代Linux系统启动的连锁效应:一个损坏的驱动程序,足以让整个精密的引导流程在第一步就宣告失败。通过Live USB和Chroot,我们获得了在系统外部进行“心脏搭桥手术”的能力,最终清除了病灶,恢复了系统的健康。希望这篇“急救”指南能为您提供解决此类棘手问题的信心和方法。 参考资料 System76 Official Bootloader Repair Guide: https://support.system76.com/articles/bootloader/ 最后再给一个装驱动检查各种东西版本的命令集合吧: #!/bin/bash # NVIDIA & CUDA 环境综合诊断命令集合 (简洁版) echo "=============== HARDWARE ===============" # 检查显卡硬件、驱动及内核模块使用情况 lspci -k | grep -A 3 -i "VGA|3D|Display" echo "\n=============== KERNEL & OS ===============" # 查看当前运行内核、已安装内核及系统版本 uname -r ls /boot/vmlinuz-* lsb_release -a echo "\n=============== DRIVER MODULES ===============" # 检查NVIDIA内核模块加载状态 lsmod | grep nvidia # 检查DKMS编译状态 (非常关键) dkms status # 查看已加载驱动的版本 (如果模块已加载) cat /proc/driver/nvidia/version echo "\n=============== PACKAGES (APT) ===============" # 查看所有已安装的NVIDIA和CUDA相关软件包 dpkg -l | grep -i nvidia echo "---" dpkg -l | grep -i cuda # 查看关键包的软件源策略 echo "---" apt-cache policy nvidia-dkms-$(dpkg -l | grep -o 'nvidia-dkms-[0-9]\+' | head -n 1 | cut -d- -f3) apt-cache policy cuda-toolkit echo "\n=============== NVIDIA & CUDA STATUS ===============" # 检查NVIDIA驱动通信状态 nvidia-smi # 检查CUDA编译器版本 nvcc --version # 检查OpenGL渲染器 glxinfo | grep "OpenGL renderer" echo "\n=============== SYSTEM LOGS (LAST 20) ===============" # 从内核日志和系统日志中筛选最新的NVIDIA相关错误 dmesg | grep -i -E "nvidia|nvrm" | tail -n 20 echo "---" journalctl -b | grep -i -E "nvidia|nvrm" | tail -n 20 echo -e "\n诊断完毕。"
Techniques
· 2025-10-08
CentOS 7 升级到 Rocky Linux 8/9 完整指南
CentOS 7 升级到 Rocky Linux 8/9 完整指南 概述 随着 CentOS 7 于 2024 年 6 月 30 日正式停止维护,众多企业面临系统迁移的紧迫需求。Rocky Linux 作为 CentOS 的完美替代方案,为用户提供了稳定可靠的企业级解决方案。 本文将手把手教你使用 ELevate 项目和 Leapp 框架,实现从 CentOS 7 到 Rocky Linux 8/9 的无痛升级。 项目主页链接: ELevate项目主页:https://almalinux.org/elevate/ Rocky Linux官方网站:https://rockylinux.org/ CentOS官方网站:https://www.centos.org/ 重要警告: 升级前务必备份所有重要数据并创建系统快照 生产环境推荐采用全新安装而非原地升级 原地升级存在一定风险,请先在测试环境验证 第一阶段:CentOS 7 升级到 Rocky Linux 8 准备工作 1. 系统备份 创建系统快照(虚拟机环境)或备份重要配置和数据目录。 2. 修复损坏的软件源(如需要) cd /etc/yum.repos.d mkdir bak mv *.repo bak/ # 使用阿里云标准源 # 阿里云CentOS镜像:http://mirrors.aliyun.com/repo/ curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo # 修复EPEL源配置(如已安装) if [ -f "bak/epel.repo" ]; then cp bak/epel.repo /etc/yum.repos.d/ sed -i 's/^metalink=/#metalink=/g' /etc/yum.repos.d/epel.repo sed -i 's/^#baseurl=/baseurl=/g' /etc/yum.repos.d/epel.repo sed -i 's|download.fedoraproject.org/pub|mirrors.aliyun.com|g' /etc/yum.repos.d/epel.repo fi yum clean all yum makecache yum install epel-release -y yum update -y 3. 检查系统状态 # 检查内核版本 rpm -qa | grep kernel uname -r cat /etc/redhat-release # 清理旧内核(如需要) # sudo yum remove kernel-3.10.0-1127.el7.x86_64 kernel-devel-3.10.0-1127.el7.x86_64 安装升级工具 1. 安装 ELevate 和 Leapp # 下载并安装 ELevate 仓库 # ELevate仓库地址:https://repo.almalinux.org/elevate/ curl -k -L -o /tmp/elevate-release-latest-el7.noarch.rpm https://repo.almalinux.org/elevate/elevate-release-latest-el7.noarch.rpm yum localinstall -y /tmp/elevate-release-latest-el7.noarch.rpm # 修复ELevate仓库SSL证书问题 cat > /etc/yum.repos.d/ELevate.repo << 'EOF' # ELevate project repo for el7 [elevate] name=ELevate baseurl=https://repo.almalinux.org/elevate/el7/$basearch/ gpgcheck=1 enabled=1 priority=90 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ELevate sslverify=0 ## Sources [elevate-source] name=ELevate - Source baseurl=https://repo.almalinux.org/elevate/el7/SRPMS/ gpgcheck=1 enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ELevate sslverify=0 EOF # 清理缓存并安装升级工具 yum clean all yum install -y leapp-upgrade leapp-data-rocky # 移除可能冲突的包 yum remove javapackages-tools -y # CUDA 相关包会被移除 执行升级 1. 预升级检查 leapp preupgrade 说明:预升级检查会生成报告文件 /var/log/leapp/leapp-report.txt,包含所有潜在问题和解决方案。 2. 执行升级 leapp upgrade 这需要一段时间,大概十几分钟,请保持网络稳定。即使远程运行也可以实时查看/var/log/leapp/leapp-upgrade.log来知道安装进度 这里用cc远程弄了一次 注意:Conda 环境可能在重启后出现冲突,但通常多次重启后会自动解决。 3. 重启系统 reboot 这里又得等好一会,执行剩下的升级。系统会自动重启两次,完成后 GRUB 菜单会显示 Rocky Linux 条目。 常见问题解决 1. yum锁定问题 如遇到 “Another app is currently holding the yum lock” 错误: # 强制杀掉相关进程 pkill -9 yum pkill -9 PackageKit pkill -9 packagekitd # 删除锁文件 rm -f /var/run/yum.pid # 彻底停用PackageKit systemctl stop packagekit systemctl disable packagekit systemctl mask packagekit # 禁用PackageKit插件 echo 'enabled=0' > /etc/yum/pluginconf.d/refresh-packagekit.conf 2. EPEL仓库metalink错误 # 修复EPEL仓库配置 sed -i 's/^metalink=/#metalink=/g' /etc/yum.repos.d/epel.repo sed -i 's/^#baseurl=/baseurl=/g' /etc/yum.repos.d/epel.repo sed -i 's|download.fedoraproject.org/pub|mirrors.aliyun.com|g' /etc/yum.repos.d/epel.repo 3. BTRFS 相关错误 如遇到 “btrfs has been removed from anolis8” 错误,这通常是正常的,因为大多数系统并未使用 btrfs 分区。 4. 外部仓库包冲突 # 移除可能冲突的 EPEL 包 yum remove <package_name> 5. Leapp升级网络连接失败 如果遇到 Failed to synchronize cache for repo 'rocky8-*' 错误: # 创建leapp专用DNF配置(解决代理兼容性问题) mkdir -p /etc/leapp/files cat > /etc/leapp/files/dnf.conf << 'EOF' [main] gpgcheck=1 installonly_limit=3 clean_requirements_on_remove=True best=True skip_if_unavailable=False proxy=socks5://127.0.0.1:1080 sslverify=0 timeout=300 retries=10 EOF # 修复软件源配置(使用直接URL代替mirrorlist) cp /etc/leapp/files/leapp_upgrade_repositories.repo{,.backup} sed -i 's|^mirrorlist=.*|#&|; s|^#baseurl=.*|baseurl=https://download.rockylinux.org/pub/rocky/8/BaseOS/x86_64/os/|' /etc/leapp/files/leapp_upgrade_repositories.repo sed -i '/^\[/a sslverify=0' /etc/leapp/files/leapp_upgrade_repositories.repo # 清理并重试 rm -rf /var/lib/leapp/* /tmp/leapp_* leapp upgrade --no-rhsm --target 8.10 6. 升级中断恢复 # 尝试恢复升级(如果支持) leapp upgrade --resume --no-rhsm # 如果不支持恢复,清理后重新开始 rm -rf /var/lib/leapp/* /tmp/leapp_* leapp upgrade --no-rhsm --target 8.10 GRUB引导故障修复指南 常见GRUB问题 升级过程中可能遇到GRUB引导失败,这是leapp升级的已知问题。典型症状包括: 重启后进入GRUB命令行模式 内核文件丢失或无法找到 系统无法正常启动 参考资源: Red Hat GRUB问题解决方案:https://access.redhat.com/solutions/7004146 GRUB修复指南:https://phoenixnap.com/kb/grub-rescue CentOS GRUB救援命令:https://linuxhint.com/grub_rescue_commands_centos/ 方法1:使用Rocky Linux 8救援模式修复 # 1. 从Rocky Linux 8安装ISO启动 # 2. 选择 "Troubleshooting" -> "Rescue a Rocky Linux system" # 3. 选择挂载文件系统选项 "1" # 4. 进入chroot环境 chroot /mnt/sysimage # 5. 重新安装GRUB和内核 grub2-install /dev/sda grub2-mkconfig -o /boot/grub2/grub.cfg # 6. 如果内核丢失,重新安装 dnf install kernel # 7. 退出并重启 exit reboot 方法2:GRUB命令行紧急启动 如果在grub>提示符下,尝试以下命令: # 加载LVM模块 grub> insmod lvm # 查看可用分区 grub> ls # 设置根分区(根据实际情况调整) grub> set root=(lvm/centos-root) # 手动加载内核(版本号需要根据实际情况调整) grub> linux /boot/vmlinuz-4.18.0-553.el8_10.x86_64 root=/dev/mapper/centos-root ro # 加载initrd grub> initrd /boot/initramfs-4.18.0-553.el8_10.x86_64.img # 启动系统 grub> boot 方法3:预防措施 # 升级前检查磁盘空间(GRUB需要至少1024KB空间) df -h /boot # 备份当前GRUB配置 cp /boot/grub2/grub.cfg /boot/grub2/grub.cfg.backup # 确保系统更新到最新 yum update -y 第二阶段:Rocky Linux 8 升级到 Rocky Linux 9 准备工作 参考链接: Phoenix NAP 升级指南:https://phoenixnap.com/kb/upgrade-rocky-linux-8-to-9 Vultr 升级文档:https://docs.vultr.com/how-to-upgrade-from-rocky-linux-8-to-rocky-linux-9#upgrade-rocky-linux-8-to-rocky-linux-9 ZJU 镜像站文档:https://mirrors.zju.edu.cn/docs/rocky/ 1. 安装 Rocky Linux 9 GPG 密钥 # 浙江大学Rocky Linux镜像:https://mirrors.zju.edu.cn/rocky/ wget https://mirrors.zju.edu.cn/rocky/9.5/BaseOS/x86_64/os/Packages/r/rocky-gpg-keys-9.5-1.2.el9.noarch.rpm sudo rpm -ivh rocky-gpg-keys-9.5-1.2.el9.noarch.rpm 2. 备份软件源配置 cp -r /etc/yum.repos.d/ /etc/yum.repos.d.bak8 3. 更新软件源为浙大镜像 方法 1:批量更新 EPEL 源 for repo_file in /etc/yum.repos.d/*.repo; do sed -e 's!^metalink=!#metalink=!g' \ -e 's!^#baseurl=!baseurl=!g' \ -e 's!https://download\.example/pub/epel/!https://mirrors.zju.edu.cn/epel/!g' \ -e 's!https://mirrors\.fedoraproject\.org/metalink!#https://mirrors.fedoraproject.org/metalink!g' \ -i "$repo_file" done 方法 2:更新 Rocky 官方源 sed -e 's|^mirrorlist=|#mirrorlist=|g' \ -e 's|^baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.zju.edu.cn/rocky|g' \ -i.bak \ /etc/yum.repos.d/Rocky-AppStream.repo \ /etc/yum.repos.d/Rocky-BaseOS.repo \ /etc/yum.repos.d/Rocky-Extras.repo \ /etc/yum.repos.d/Rocky-PowerTools.repo 4. 清理和准备升级环境 # 备份 Elevate.repo 文件 mv /etc/yum.repos.d/ELevate.repo /etc/yum.repos.d/Elevate.repo.bak # 清除缓存并重建 sudo yum clean all sudo yum makecache sudo dnf upgrade --refresh # 重新安装 xl2tpd(用于 ZJU 网络) sudo yum remove xl2tpd sudo yum install xl2tpd 执行升级到 Rocky 9 1. 修改 DNF 配置 # 取消 exclude 行的注释 sudo sed -i 's/^exclude=/#exclude=/g' /etc/dnf/dnf.conf 2. 移除旧版本包和依赖 # 移除 Leapp 相关包 sudo dnf remove leapp leapp-upgrade-el7toel8 python2-leapp # 移除其他冲突包 sudo dnf -y remove rpmconf yum-utils epel-release sudo rm -rf /usr/share/redhat-logos # 移除 Python 2 相关包 sudo dnf remove --skip-broken --nobest python2 python2-libs python2-pip python2-setuptools \ python2-requests python2-pytz python2-coverage python2-idna python2-backports python2-lxml \ python2-backports-ssl_match_hostname python2-ipaddress pygobject2 python2-pysocks \ python2-urllib3 python2-pyyaml python2-chardet python2-six python2-cairo # 移除其他冲突组件 sudo dnf remove make-devel iptables-ebtables 3. 安装升级工具 sudo dnf install dnf-plugin-system-upgrade 4. 强制移除遗留包 sudo rpm -e --nodeps leapp leapp-upgrade-el7toel8 python2-leapp python2 python2-libs 5. 导入 GPG 密钥 # Rocky Linux官方GPG密钥:https://dl.rockylinux.org/pub/rocky/ sudo rpm --import https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9 6. 执行系统升级 sudo dnf -y --releasever=9 --allowerasing --setopt=deltarpm=false distro-sync sudo rpm --rebuilddb sudo reboot 升级后验证和清理 1. 验证系统版本 cat /etc/redhat-release cat /etc/os-release 2. 完成系统更新 sudo dnf update --allowerasing 3. 重新安装 CUDA(如需要) sudo dnf module install nvidia-driver:latest dnf install nvidia-driver-cuda -y # NVIDIA CUDA官方仓库:https://developer.download.nvidia.com/compute/cuda/repos/ sudo dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel9/x86_64/cuda-rhel9.repo sudo dnf clean all sudo dnf -y install cuda-toolkit-12-6 EPEL 9 仓库配置 创建或更新 /etc/yum.repos.d/epel.repo: [epel] name=Extra Packages for Enterprise Linux $releasever - $basearch baseurl=https://mirrors.zju.edu.cn/epel/$releasever/Everything/$basearch/ #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-$releasever&arch=$basearch&infra=$infra&content=$contentdir enabled=1 gpgcheck=1 countme=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-$releasever [epel-debuginfo] name=Extra Packages for Enterprise Linux $releasever - $basearch - Debug baseurl=https://mirrors.zju.edu.cn/epel/$releasever/Everything/$basearch/debug/ #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-$releasever&arch=$basearch&infra=$infra&content=$contentdir enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-$releasever gpgcheck=1 [epel-source] name=Extra Packages for Enterprise Linux $releasever - $basearch - Source baseurl=https://mirrors.zju.edu.cn/epel/$releasever/Everything/source/tree/ #mirrorlink=https://mirrors.fedoraproject.org/metalink?repo=epel-source-$releasever&arch=$basearch&infra=$infra&content=$contentdir enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-$releasever gpgcheck=1 总结 本指南提供了从 CentOS 7 到 Rocky Linux 9 的完整升级路径: 阶段一:CentOS 7 → Rocky Linux 8(使用 Leapp) 阶段二:Rocky Linux 8 → Rocky Linux 9(使用 DNF 系统升级) 最佳实践建议: 生产环境建议采用全新安装而非原地升级 升级前充分测试并制定回滚计划 定期备份系统和数据 关注官方文档更新 相关教程和参考资料 官方文档 Rocky Linux 迁移官方指南:https://docs.rockylinux.org/guides/migrate2rocky/ ELevate 项目快速入门指南:https://wiki.almalinux.org/elevate/ELevate-quickstart-guide.html AlmaLinux ELevate 项目主页:https://almalinux.org/elevate/ ELevate 项目 - CloudLinux:https://cloudlinux.com/elevate/ Red Hat Leapp 升级文档:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/upgrading_from_rhel_7_to_rhel_8/ 详细教程 从 CentOS 7 迁移到 Rocky Linux 8 详细指南 - Linuxiac:https://linuxiac.com/migrating-from-centos-7-to-rocky-linux-8/ CentOS 7 到 Rocky Linux 8 转换教程 - First2Host:https://first2host.co.uk/blog/migrate-centos-7-rocky-linux-8/ CentOS 7.x 原地升级到 Rocky Linux 8.x - JetPatch:https://kc.jetpatch.com/hc/en-us/articles/28894194238989-In-place-upgrade-from-CentOS-7-x-to-Rocky-linux-8-x CentOS 7 迁移到 Rocky Linux 9 - phoenixNAP:https://phoenixnap.com/kb/migrate-centos-to-rocky-linux CentOS 7 迁移到 Rocky Linux 9 指南 - Medium:https://medium.com/@redswitches/how-to-migrate-centos-7-to-rocky-linux-9-bc00db9e4ee7 Rocky 8 到 9 升级 Phoenix NAP 升级指南:https://phoenixnap.com/kb/upgrade-rocky-linux-8-to-9 Vultr 升级文档:https://docs.vultr.com/how-to-upgrade-from-rocky-linux-8-to-rocky-linux-9#upgrade-rocky-linux-8-to-rocky-linux-9 Rocky Linux 8 到 9 升级 - Linuxiac:https://linuxiac.com/upgrade-rocky-linux-8-to-rocky-linux-9/ Rocky Linux 8 到 9 升级 - Shapehost:https://shape.host/resources/how-to-upgrade-from-rocky-linux-8-to-rocky-linux-9 技术资源和工具 GitHub - CentOS 7 升级到 8 脚本:https://gist.github.com/Trogvars/d93f8e370e9d01d4afc6e2a7e8c69ab2 Linux Notes: ELevate - leapp 迁移工具:https://neilrieck.net/docs/linux_notes_leapp.html CentOS 到 Rocky Linux 迁移规划 - OpenLogic:https://www.openlogic.com/blog/planning-centos-rocky-linux-migration CIQ Ascender CentOS 7 到 Rocky 8 迁移:https://ciq.com/blog/ascender-migrates-host-from-centos-7-to-rocky-8/ GRUB故障排查资源 GRUB修复指南 - Phoenix NAP:https://phoenixnap.com/kb/grub-rescue GRUB救援模式修复 - HowToForge:https://www.howtoforge.com/tutorial/repair-linux-boot-with-grub-rescue/ CentOS GRUB救援命令:https://linuxhint.com/grub_rescue_commands_centos/ Red Hat GRUB问题解决方案:https://access.redhat.com/solutions/7004146 镜像源和下载 浙江大学 Rocky Linux 镜像站:https://mirrors.zju.edu.cn/docs/rocky/ 阿里云 CentOS 镜像源:http://mirrors.aliyun.com/repo/ 阿里云 EPEL 镜像:https://mirrors.aliyun.com/epel/ Rocky Linux 官方下载:https://download.rockylinux.org/ ELevate 项目仓库:https://repo.almalinux.org/elevate/ 社区支持 Rocky Linux 官方论坛:https://forums.rockylinux.org/ CentOS 官方论坛:https://forums.centos.org/ AlmaLinux 社区聊天室(~migration 频道):https://chat.almalinux.org/ Server Fault 社区:https://serverfault.com/ Red Hat 客户门户:https://access.redhat.com/ 官方网站和文档 Rocky Linux 官方文档:https://docs.rockylinux.org/ ELevate 项目:https://wiki.almalinux.org/elevate/ 浙江大学镜像站:https://mirrors.zju.edu.cn/docs/rocky/ CentOS 官方文档:https://docs.centos.org/ NVIDIA CUDA 官方文档:https://docs.nvidia.com/cuda/
Techniques
· 2025-10-08
CentOS 7升级Rocky Linux 8无网络环境解决方案
CentOS 7升级Rocky Linux 8无网络环境解决方案 无网络环境升级解决方案 场景说明 在实际生产环境中,很多服务器出于安全考虑无法直接访问互联网。比如你浙,zjunet已经无法在老机子上安装了,Linux上无线网卡又不好使。本文将详细介绍如何在这种受限网络环境下,成功完成CentOS 7到Rocky Linux 8的平滑升级。 本文档参考了ELevate项目官方文档和社区最佳实践,ELevate项目主页:https://almalinux.org/elevate/ 方法一:SSH动态代理隧道 适用场景 有一台可以联网的跳板机 待升级机器可以SSH连接到跳板机 跳板机可以SSH连接到待升级机器 参考SSH隧道配置指南:https://www.ssh.com/academy/ssh/tunneling 配置步骤 1. 在待升级机器上建立SSH隧道 # 在待升级机器上执行(后台运行) ssh -D 1080 user@跳板机IP & # 示例:ssh -D 1080 gxf1212@10.77.14.189 & 2. 配置yum使用SOCKS5代理 # 在yum.conf中添加代理配置 echo 'proxy=socks5://127.0.0.1:1080' >> /etc/yum.conf # 验证代理是否工作 curl --proxy socks5://127.0.0.1:1080 -I http://www.baidu.com 3. 解决常见代理问题 # 如果遇到SSL证书过期问题,跳过SSL验证 # 对于需要下载的rpm包 curl --proxy socks5://127.0.0.1:1080 -k -L -o /tmp/package.rpm https://example.com/package.rpm # 为ELevate仓库添加SSL跳过设置 echo 'sslverify=0' >> /etc/yum.repos.d/ELevate.repo 方法二:离线软件包准备 适用场景 完全无网络环境 需要预先在联网机器上准备软件包 准备软件包(在联网机器上执行) 1. 下载ELevate相关包 # 创建下载目录 mkdir -p /tmp/centos7-upgrade-packages # 下载ELevate仓库包 # ELevate仓库地址:https://repo.almalinux.org/elevate/ curl -k -L -o /tmp/centos7-upgrade-packages/elevate-release-latest-el7.noarch.rpm \ https://repo.almalinux.org/elevate/elevate-release-latest-el7.noarch.rpm # 配置临时ELevate仓库 yum install -y /tmp/centos7-upgrade-packages/elevate-release-latest-el7.noarch.rpm # 下载leapp相关包及其依赖 yumdownloader --resolve --destdir=/tmp/centos7-upgrade-packages \ leapp-upgrade leapp-data-rocky 2. 传输软件包到目标机器 # 使用scp传输软件包目录 scp -r /tmp/centos7-upgrade-packages/ root@target-server:/tmp/ # 或使用rsync rsync -avz /tmp/centos7-upgrade-packages/ root@target-server:/tmp/centos7-upgrade-packages/ 在目标机器上安装(无网络环境) # 安装ELevate仓库 yum localinstall -y /tmp/centos7-upgrade-packages/elevate-release-latest-el7.noarch.rpm # 安装所有下载的包 yum localinstall -y /tmp/centos7-upgrade-packages/*.rpm # 继续正常的升级流程 leapp preupgrade leapp upgrade reboot 软件源配置文件模板 CentOS 7 基础源配置 创建 /etc/yum.repos.d/CentOS-Base.repo: 阿里云CentOS镜像源:https://mirrors.aliyun.com/centos/ [base] name=CentOS-7 - Base - mirrors.aliyun.com baseurl=http://mirrors.aliyun.com/centos/7/os/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [updates] name=CentOS-7 - Updates - mirrors.aliyun.com baseurl=http://mirrors.aliyun.com/centos/7/updates/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [extras] name=CentOS-7 - Extras - mirrors.aliyun.com baseurl=http://mirrors.aliyun.com/centos/7/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [centosplus] name=CentOS-7 - Plus - mirrors.aliyun.com baseurl=http://mirrors.aliyun.com/centos/7/centosplus/$basearch/ gpgcheck=1 enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 EPEL 7 源配置(修复版) 创建 /etc/yum.repos.d/epel.repo: EPEL项目主页:https://fedoraproject.org/wiki/EPEL 阿里云EPEL镜像源:https://mirrors.aliyun.com/epel/ [epel] name=Extra Packages for Enterprise Linux 7 - $basearch baseurl=http://mirrors.aliyun.com/epel/7/$basearch #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch failovermethod=priority enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 [epel-debuginfo] name=Extra Packages for Enterprise Linux 7 - $basearch - Debug baseurl=http://mirrors.aliyun.com/epel/7/$basearch/debug #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 gpgcheck=1 [epel-source] name=Extra Packages for Enterprise Linux 7 - $basearch - Source baseurl=http://mirrors.aliyun.com/epel/7/SRPMS #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 gpgcheck=1 ELevate 源配置(修复SSL问题版) 创建 /etc/yum.repos.d/ELevate.repo: ELevate项目仓库:https://repo.almalinux.org/elevate/ # ELevate project repo for el7 [elevate] name=ELevate baseurl=https://repo.almalinux.org/elevate/el7/$basearch/ gpgcheck=1 enabled=1 priority=90 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ELevate sslverify=0 ## Sources [elevate-source] name=ELevate - Source baseurl=https://repo.almalinux.org/elevate/el7/SRPMS/ gpgcheck=1 enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ELevate sslverify=0 代理配置最佳实践 yum.conf 代理配置 [main] cachedir=/var/cache/yum/$basearch/$releasever keepcache=0 debuglevel=2 logfile=/var/log/yum.log exactarch=1 obsoletes=1 gpgcheck=1 plugins=1 installonly_limit=5 bugtracker_url=http://bugs.centos.org/set_project.php?project_id=23&ref=http://bugs.centos.org/bug_report_page.php?category=yum distroverpkg=centos-release # 代理配置(根据实际情况选择一种) # HTTP代理 #proxy=http://proxy-server:port #proxy_username=username #proxy_password=password # SOCKS5代理(推荐用于SSH隧道) proxy=socks5://127.0.0.1:1080 关键修复步骤 leapp升级网络失败修复 如果遇到 Failed to synchronize cache for repo 'rocky8-*' 错误: # 1. 创建leapp专用DNF配置 mkdir -p /etc/leapp/files cat > /etc/leapp/files/dnf.conf << 'EOF' [main] gpgcheck=1 installonly_limit=3 clean_requirements_on_remove=True best=True skip_if_unavailable=False proxy=socks5://127.0.0.1:1080 sslverify=0 timeout=300 retries=10 EOF # 2. 更新系统DNF配置 cat > /etc/dnf/dnf.conf << 'EOF' [main] gpgcheck=1 installonly_limit=3 clean_requirements_on_remove=True best=True skip_if_unavailable=False proxy=socks5://127.0.0.1:1080 sslverify=0 timeout=300 retries=10 EOF # 3. 修复Rocky Linux 8软件源配置(使用直接URL而非mirrorlist) cp /etc/leapp/files/leapp_upgrade_repositories.repo /etc/leapp/files/leapp_upgrade_repositories.repo.backup cat > /etc/leapp/files/leapp_upgrade_repositories.repo << 'EOF' [rocky8-baseos] name=Rocky Linux 8 - BaseOS baseurl=https://download.rockylinux.org/pub/rocky/8/BaseOS/x86_64/os/ gpgcheck=1 enabled=1 gpgkey=file:///etc/leapp/repos.d/system_upgrade/common/files/rpm-gpg/8/RPM-GPG-KEY-Rocky-8 sslverify=0 [rocky8-appstream] name=Rocky Linux 8 - AppStream baseurl=https://download.rockylinux.org/pub/rocky/8/AppStream/x86_64/os/ gpgcheck=1 enabled=1 gpgkey=file:///etc/leapp/repos.d/system_upgrade/common/files/rpm-gpg/8/RPM-GPG-KEY-Rocky-8 sslverify=0 [rocky8-extras] name=Rocky Linux 8 - Extras baseurl=https://download.rockylinux.org/pub/rocky/8/extras/x86_64/os/ gpgcheck=1 enabled=1 gpgkey=file:///etc/leapp/repos.d/system_upgrade/common/files/rpm-gpg/8/RPM-GPG-KEY-Rocky-8 sslverify=0 EOF # 4. 清理leapp状态并重试 rm -rf /var/lib/leapp/* /tmp/leapp_* leapp upgrade --no-rhsm --target 8.10 升级中断恢复 如果升级过程中断: # 1. 检查leapp状态 ls -la /var/lib/leapp/ # 2. 尝试恢复升级(如果支持) leapp upgrade --resume --no-rhsm # 3. 如果resume不支持,清理后重新开始 rm -rf /var/lib/leapp/* /tmp/leapp_* leapp upgrade --no-rhsm --target 8.10 GRUB引导修复指南 常见GRUB问题 如果升级后遇到GRUB引导问题,这是leapp升级的已知问题。参考解决方案: Red Hat GRUB修复文档:https://access.redhat.com/solutions/7004146 Rocky Linux救援模式指南:https://docs.rockylinux.org/guides/ GRUB修复社区文档:https://phoenixnap.com/kb/grub-rescue # 从Rocky Linux 8救援盘启动后执行: chroot /mnt/sysimage grub2-install /dev/sda grub2-mkconfig -o /boot/grub2/grub.cfg GRUB命令行紧急启动 # 在grub>提示符下执行: insmod lvm set root=(lvm/centos-root) linux /boot/vmlinuz-4.18.0-553.el8_10.x86_64 root=/dev/mapper/centos-root ro initrd /boot/initramfs-4.18.0-553.el8_10.x86_64.img boot GRUB救援命令参考:https://linuxhint.com/grub_rescue_commands_centos/ 故障排查指南 1. 验证网络连通性 # 测试基本网络连接 ping -c 3 8.8.8.8 # 测试域名解析 nslookup mirrors.aliyun.com # 测试HTTP连接 curl -I http://mirrors.aliyun.com/ # 测试HTTPS连接 curl -I https://mirrors.aliyun.com/ # 测试代理连接 curl --proxy socks5://127.0.0.1:1080 -I http://www.baidu.com 2. 检查SSH隧道状态 # 检查SSH隧道进程 ps aux | grep "ssh -D" # 检查监听端口 netstat -tlnp | grep 1080 # 重新建立SSH隧道(如果断开) ssh -D 1080 user@jumphost & 3. 清理和重试 # 清理yum缓存 yum clean all rm -rf /var/cache/yum/* # 重新生成缓存 yum makecache # 测试软件源 yum repolist 注意事项 SSH隧道稳定性:确保SSH隧道在整个升级过程中保持稳定,建议使用screen或tmux来管理长时间运行的任务。 带宽考虑:升级过程需要下载大量软件包,确保网络带宽足够。 防火墙设置:检查跳板机和目标机器的防火墙配置,确保必要的端口开放。 备份重要性:无网络环境下出现问题更难修复,务必在升级前做好完整备份。 测试环境:建议先在类似的测试环境中验证整个流程。 相关资源链接 官方文档: ELevate项目主页:https://almalinux.org/elevate/ Rocky Linux官方文档:https://docs.rockylinux.org/ Red Hat leapp工具文档:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/upgrading_from_rhel_7_to_rhel_8/ CentOS官方文档:https://docs.centos.org/ 镜像源: 阿里云CentOS镜像:https://mirrors.aliyun.com/centos/ 阿里云EPEL镜像:https://mirrors.aliyun.com/epel/ Rocky Linux官方下载:https://download.rockylinux.org/ ELevate项目仓库:https://repo.almalinux.org/elevate/ 技术支持: Rocky Linux论坛:https://forums.rockylinux.org/ CentOS论坛:https://forums.centos.org/ Server Fault社区:https://serverfault.com/ Red Hat客户门户:https://access.redhat.com/ 故障排查资源: GRUB修复指南:https://phoenixnap.com/kb/grub-rescue SSH隧道配置:https://www.ssh.com/academy/ssh/tunneling GRUB救援命令:https://linuxhint.com/grub_rescue_commands_centos/ Linux Foundation GRUB指南:https://www.linuxfoundation.org/blog/blog/classic-sysadmin-how-to-rescue-a-non-booting-grub-2-on-linux 注:本文档整合了官方指南和社区最佳实践,包含了无网络环境的完整解决方案,适用于 2025 年的系统迁移需求。如遇到GRUB引导问题,建议优先考虑使用Rocky Linux 8救援盘进行修复,或在测试环境中先验证升级流程的完整性。
Techniques
· 2025-10-08
Ubuntu Virtual Memory (Swap) Setup Tutorial: Enhance System Performance
在 Ubuntu 中增加虚拟内存(Swap)教程 在 Ubuntu 系统中增加虚拟内存(即交换空间,Swap)可以有效提升系统在内存不足时的性能。以下是详细的操作步骤: 一、检查当前交换空间 首先,您需要检查当前系统的交换空间情况。打开终端并运行以下命令: sudo swapon --show 如果命令没有输出,说明当前系统没有启用交换空间。如果有输出,则会显示现有交换文件或分区的信息(例如 /swapfile)。 二、创建新的交换文件 方法一:使用 fallocate 命令(推荐) 运行以下命令创建一个新的交换文件: sudo fallocate -l 4G /swapfile_new -l 4G:指定交换文件大小为 4GB。您可以根据需求调整大小,例如使用 8G 表示 8GB。 /swapfile_new:新交换文件的路径。您可以自定义文件名,但需确保后续步骤中路径一致。 方法二:使用 dd 命令(若 fallocate 不可用) 如果 fallocate 命令不可用,可以使用 dd 命令创建交换文件: sudo dd if=/dev/zero of=/swapfile_new bs=1G count=4 bs=1G:每次写入 1GB 数据。 count=4:写入 4 次,生成 4GB 文件。 三、设置交换文件的权限 为了安全起见,设置交换文件的权限,使其仅限 root 用户访问: sudo chmod 600 /swapfile_new 四、格式化交换文件 将创建的文件标记为交换空间: sudo mkswap /swapfile_new 五、启用交换文件 运行以下命令启用新创建的交换文件: sudo swapon /swapfile_new 六、验证交换空间 检查新增的交换空间是否生效: sudo swapon --show 您还可以查看内存使用情况以确认交换空间的变化: free -h 七、配置开机自动挂载 为了使交换文件在系统重启后仍然有效,需要将其添加到 /etc/fstab 文件中: 打开 /etc/fstab 文件进行编辑: sudo nano /etc/fstab 在文件末尾添加以下内容: /swapfile_new none swap sw 0 0 保存并退出编辑器(在 nano 中,按 Ctrl+O 保存,按 Ctrl+X 退出)。 注意事项 调整交换文件大小:根据系统需求和使用场景调整交换文件的大小。一般建议交换文件大小为物理内存的 1-2 倍,但具体大小取决于您的应用场景。 权限管理:确保交换文件的权限设置正确,避免非授权访问。 性能考量:虽然增加交换空间可以缓解内存不足的问题,但过度依赖交换空间可能会降低系统性能,因为磁盘 I/O 速度远低于内存。 通过以上步骤,您可以成功增加 Ubuntu 系统的虚拟内存(Swap),从而提升系统的整体性能和稳定性。 希望这份教程对您有所帮助!如果您在操作过程中遇到任何问题,欢迎随时提问。 Pandoc 生成 PDF 时字体问题解决方案教程 一、问题概述 在使用 Pandoc 将 Markdown 文件生成 PDF 时,如果指定使用 Times New Roman 字体,可能会遇到错误。这是因为 Times New Roman 是 Windows 系统的默认字体,在 Linux 或 macOS 上默认未安装。此外,对于中文支持,也需要确保系统中存在相应的中文字体。 二、检查字体是否安装 在 Linux 系统中 打开终端,运行以下命令查看系统中已安装的字体: fc-list :lang=zh # 查看中文字体 fc-list | grep "Times New Roman" # 查找 Times New Roman 字体 如果没有输出,说明系统中未安装该字体。 在 macOS 系统中 使用 Font Book 应用程序检查字体是否安装。 在 Windows 系统中 打开“字体”文件夹(通常在 C:\Windows\Fonts),查找“Times New Roman”字体。 三、安装所需字体 安装 Times New Roman 字体 对于 Ubuntu/Debian 系统: 运行以下命令安装 Microsoft 核心字体,其中包含 Times New Roman: sudo apt-get update sudo apt-get install ttf-mscorefonts-installer 在安装过程中,可能需要接受许可协议。安装完成后,运行以下命令刷新字体缓存: sudo fc-cache -fv 对于 CentOS/RHEL 系统: 使用以下命令安装字体: sudo yum install curl curl-devel sudo rpm -Uvh http://li.nux.ro/download/fedora/epel/5/i386/epel-release-5-4.noarch.rpm sudo yum install ttf-mscorefonts-installer 对于 macOS 系统: 从官方渠道下载并安装 Microsoft Office for Mac,它会附带安装 Times New Roman 字体。或者,您可以手动下载字体文件并安装。 安装中文支持字体 如果您需要在 PDF 中显示中文,还需要安装中文字体。例如,在 Ubuntu/Debian 系统上,可以安装 texlive-lang-chinese 包: sudo apt install texlive-lang-chinese 该包包含中文支持的宏包(如 ctex),是 Debian 官方维护的包,具有良好的兼容性。 四、配置 Pandoc 使用正确字体 在 Pandoc 命令中指定字体时,确保使用的字体名称与系统中实际存在的字体名称完全匹配。例如: pandoc input.md -o output.pdf --pdf-engine=xelatex --css style.css -V mainfont="Times New Roman" -V CJKmainfont="AR PL UMing CN" mainfont:指定西文字体。 CJKmainfont:指定中文字体。 五、生成 PDF 的 Python 函数示例 以下是一个使用 Pandoc 生成 PDF 的 Python 函数示例,确保路径和字体名称正确: import subprocess import logging from pathlib import Path log = logging.getLogger(__name__) def generate_pdf_with_pandoc(md_path: Path, css_path: Path, output_pdf_path: Path) -> bool: """ 使用 Pandoc 和 XeLaTeX 生成 PDF 文件。 参数: md_path: 输入的 Markdown 文件路径。 css_path: CSS 文件路径(可选)。 output_pdf_path: 输出的 PDF 文件路径。 返回: PDF 生成成功返回 True,失败返回 False。 """ log.info(f"Attempting PDF generation with Pandoc for {md_path}.") pandoc_cmd = [ 'pandoc', str(md_path), '-o', str(output_pdf_path), '--pdf-engine=xelatex', '--css', str(css_path), '-V', 'mainfont=Times New Roman', '-V', 'CJKmainfont=AR PL UMing CN' ] result = subprocess.run(pandoc_cmd, capture_output=True, text=True, encoding='utf-8') if result.returncode != 0: log.error(f"Pandoc failed. Stderr: {result.stderr}") return False log.info(f"Successfully generated PDF with Pandoc at {output_pdf_path}") return True 六、验证和测试 验证字体安装: 运行 fc-list 命令,检查是否列出了 Times New Roman 和中文字体。 确保字体名称与 Pandoc 命令中指定的名称完全一致。 测试 PDF 生成: 使用上述 Python 函数或直接运行 Pandoc 命令生成 PDF。 打开生成的 PDF 文件,检查字体显示是否正确。 七、总结 通过以上步骤,您可以解决 Pandoc 在生成 PDF 时找不到指定字体的问题。确保系统中安装了所需的字体,并在 Pandoc 命令中正确指定字体名称。对于中文支持,安装 texlive-lang-chinese 包是一个推荐的解决方案。希望这份教程能帮助您顺利完成 PDF 生成任务。 如果您在操作过程中遇到任何问题或需要进一步的帮助,欢迎随时提问。
Techniques
· 2025-10-08
【笔记整理|2023-09+2024年上半年】系统运维与故障排除实用指南
【笔记整理|2023-09+2024年上半年】系统运维与故障排除实用指南 本文汇总了Linux系统运维、远程连接、桌面环境配置以及常见故障排除的实用技巧和解决方案。 系统监控与性能诊断 系统兼容性问题识别 软件兼容性检查 如果PyMOL和ChimeraX都有问题,通常是系统级别的问题,需要检查: 显卡驱动是否正常 OpenGL支持是否完整 系统库文件是否缺失 键盘输入问题 在某些终端环境下,VMD无法正常响应上下左右键,这通常与gnome terminal的设置有关。 显示器相关问题 每次关闭显示器后,dash to panel任务栏会消失,系统默认的会显示,这可能是扩展与电源管理的兼容性问题。 远程连接解决方案 ToDesk使用体验 ToDesk在Linux环境下的特点: 无法在Pop!_OS中自动调整布局,但能记住布局设置 Linux版本不支持复制粘贴功能 与Windows版本功能有差异 AnyDesk配置管理 安装问题解决 Fedora AnyDesk安装问题: https://discussion.fedoraproject.org/t/cannot-install-anydesk/73854 自启动管理 Ubuntu禁用AnyDesk自启动: https://devicetests.com/disable-anydesk-autostart-ubuntu 建议直接禁用自启动功能,按需启动。 命令行工具技巧 跨平台命令对比 Windows PowerShell替代方案 在Windows系统中,没有与Linux系统中的tac命令完全相同的命令。可以使用PowerShell中的Get-Content命令和-Reverse参数来实现类似功能。 findstr命令使用 findstr命令类似于Unix系统中的grep,用于在文件中进行文本搜索: findstr "xxx" filename 文件批量处理 sed批量替换 批量文件名处理时,Linux命令更高效: # 批量替换文件中的路径 sed -i 's/E:\\GitHub-repo\\notes\\research\\/https\:\/\/cdn.jsdelivr.net\/gh\/username\/notes\@master\/research\//g' *.md # 批量替换assets路径 sed -i 's/assets\\/assets\//g' *.md ZIP压缩操作 Linux ZIP命令教程: https://www.runoob.com/linux/linux-comm-zip.html 桌面环境配置与故障排除 GNOME扩展管理 扩展兼容性问题 检查GNOME版本兼容性: gnome-shell --version 某些扩展可能在特定版本的GNOME下存在兼容性问题。 Dash to Panel配置 Dash to Panel扩展: https://extensions.gnome.org/extension/1160/dash-to-panel/ 配置注意事项: 检查GNOME Shell版本兼容性 避免与其他任务栏扩展冲突 注意电源管理对扩展的影响 工作区管理 动态工作区设置 # 禁用动态工作区,使用固定数量 gsettings set org.gnome.mutter dynamic-workspaces false 建议设置1-4个固定工作区,而不是使用默认的Home设置。 窗口管理优化 Ubuntu单击任务栏图标最小化窗口: https://cn.linux-console.net/?p=17727 多显示器配置 工作区管理在多显示器环境下的注意事项: 不是在所有监视器上都显示工作区 可以设置主显示器和辅助显示器的不同行为 Web服务故障排除 端口占用问题 # 检查端口占用情况 sudo apt-get update # 释放被占用的端口 端口释放指南: https://medium.com/@antonrosh/address-already-in-use-a-simple-guide-to-freeing-up-ports-fbc6a3822983 WebView错误处理 常见错误:Error loading webview: Error: Could not register service workers: TypeError: Failed WebView错误解决方案: https://stackoverflow.com/questions/67698176/error-loading-webview-error-could-not-register-service-workers-typeerror-fai 网络代理与连接问题 代理配置管理 # 手动设置代理 export http_proxy="http://127.0.0.1:7890" CFW代理配置 使用经验: 现在CFW不影响conda,配置manual proxy即可 无法在重启后CFW缓慢启动前连接网络,但手动配置可以工作 网络连接故障排除 重启后网络连接问题的解决方案: 检查网络服务状态 验证代理配置 测试DNS解析 检查防火墙设置 开发工具集成 Python外部程序调用 import subprocess # 调用外部程序的标准方法 def run_external_command(command): result = subprocess.run(command, shell=True, capture_output=True, text=True) return result.stdout, result.stderr 包管理集成 使用subprocess调用系统包管理器: # 调用antechamber等外部工具 def call_antechamber(input_file, output_file): cmd = f"antechamber -i {input_file} -o {output_file}" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) return result JSON数据处理 import json # 加载JSON数据的标准方法 with open('data.json', 'r') as f: data = json.load(f) 系统文档与术语 技术术语翻译 de facto:事实上的标准 Software Development Kit (SDK):软件开发工具包 编程概念 Arrow Functions JavaScript箭头函数: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions 数据库与版本控制 Git版本控制扩展 基于Git版本控制的关系型数据库Dolt: https://jasonkayzk.github.io/2024/01/21/%E5%9F%BA%E4%BA%8EGit%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6%E7%9A%84%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93Dolt/ 这种新型数据库结合了版本控制的优势。 LaTeX与文档处理 LaTeX环境配置 基础安装 # 安装LaTeX基础包 sudo apt install texlive-latex-extra # 安装XeLaTeX sudo apt install texlive-xetex # 安装BibTeX支持 sudo apt install texlive-bibtex-extra Linux LaTeX安装指南: https://linuxconfig.org/how-to-install-latex-on-ubuntu-20-04-focal-fossa-linux 中文支持 处理”LaTeX Error: File `ctexbook.cls’ not found”错误: 这个错误表明缺少CTEX包,该包用于LaTeX中文文档的排版。需要安装相应的中文支持包。 Markdown到PDF转换 VSCode Markdown PDF插件: https://github.com/yzane/vscode-markdown-pdf?tab=readme-ov-file#usage Docker容器化 Docker配置问题 Linux Docker配置: https://blognas.hwb0307.com/linux/docker/654 容器化部署在开发环境中的重要性日益增加。 API与Web开发 GitHub相关服务 GitHub Discussions快速入门: https://docs.github.com/zh/discussions/quickstart GitHub Apps Giscus: https://github.com/apps/giscus Vue.js开发 Vue.js组合式函数: https://cn.vuejs.org/guide/reusability/composables 故障排除最佳实践 系统问题诊断流程 问题重现:确认问题的可重现性 日志检查:查看系统和应用程序日志 资源监控:检查CPU、内存、磁盘使用情况 服务状态:验证相关服务的运行状态 配置验证:检查关键配置文件 权限确认:验证文件和目录权限 网络问题排查 连通性测试:ping、traceroute 端口检查:netstat、ss命令 DNS解析:nslookup、dig命令 防火墙状态:iptables、ufw检查 代理配置:环境变量和应用配置 桌面环境问题解决 重启服务:重启显示管理器 重置配置:备份后重置用户配置 扩展管理:禁用可疑扩展 兼容性检查:验证软件版本兼容性 监控与维护 系统健康检查 定期进行系统健康检查: 磁盘空间使用情况 系统更新状态 服务运行状态 网络连接质量 安全更新应用 预防性维护 定期清理临时文件 更新系统软件包 检查硬件健康状态 备份重要配置文件 监控系统性能指标 本文基于2023年9月至2024年上半年的系统运维实践整理,涵盖常见运维问题的诊断方法和解决方案
Techniques
· 2025-10-08
RAG:科研文献检索增强生成的系统架构与技术解析
引言 核心挑战的界定 在处理大规模、高度专业化的知识库(如本报告关注的”自由能微扰(FEP)与AI结合”科研文献)时,检索增强生成(Retrieval-Augmented Generation, RAG)系统面临着一个根本性挑战:语义鸿沟(semantic gap)。标准的”分块-嵌入-检索-生成”流程看似直接,但其效能往往因检索到的文本块(chunks)与用户查询的真实意图之间存在语义脱节而大打折扣。这种脱节源于一个基本假设的脆弱性:即用户查询向量与文档块向量在嵌入空间中的余弦相似度足以表征上下文的真实相关性。在自由能计算这样充满复杂术语、微妙关系和隐含知识的领域,这一假设频繁失效。其结果是,生成式大语言模型(LLM)接收到的是不完整、不相关甚至具有误导性的上下文信息,这种现象可称为”上下文投毒”(context poisoning)。这不仅导致模型生成无效或错误的回答,更从根本上破坏了RAG系统作为可靠知识引擎的核心价值。 论文主旨 要从根本上解决科研文献RAG系统中的检索精度问题,必须超越简单的线性流程,转向一种多层次、动态且深度感知上下文的系统架构。本文主张,实现高精度检索并非依赖于单一环节的优化,而是需要在RAG生命周期的每一个阶段进行系统性的、前沿的技术整合。这包括:在预检索(Pre-Retrieval)阶段,通过先进的索引和数据表征技术,最大化信息的”可发现性”;在检索(Retrieval)阶段,通过智能的查询理解与执行机制,精准定位目标知识;以及在后检索(Post-Retrieval)阶段,通过精细化的结果过滤与重排,提纯最终交付给LLM的上下文。本报告将系统性地梳理并阐述贯穿这三个阶段的最先进技术与策略,为构建下一代高精度科研RAG系统提供一份全面的架构蓝图。 第一部分:奠定基石——先进的索引与多模态数据表征 检索的质量上限,从根本上受限于索引的质量。一个无法被精准表征的知识点,无论后续检索算法多么精妙,都难以被有效发现。因此,构建高精度RAG系统的第一步,是对复杂的科研文献进行深度解析与结构化表征,从而创建一个信息丰富、语义保真且易于查询的索引。 1.1 超越固定尺寸分块:保持语义完整性的策略 朴素分块的问题 在RAG的早期实践中,固定尺寸分块(Fixed-Size Chunking)因其实现简单而被广泛采用。然而,这种方法在处理结构严谨的科研论文时,其弊端尤为突出。它会武断地切分文本,无视句子、段落乃至章节的自然边界,从而破坏信息的逻辑连贯性。一篇科研论文中,一个关键论点与其支撑证据、一个分子实体与其功能描述、一个实验方法与其结果讨论,可能因此被割裂到不同的文本块中。这种上下文的碎片化是导致后续检索失败和LLM生成质量低下的根本原因之一。 内容感知分块 (Content-Aware Chunking) 内容感知分块是解决上述问题的基础性改进。其核心思想是尊重文档固有的逻辑结构,在自然的语义边界上进行切分,以确保每个文本块都是一个相对独立且语义完整的意义单元。针对科研文献,有效的策略包括: 句子级分块:利用自然语言处理库(如NLTK、spaCy)提供的句子分割器,将文本切分为单个句子。这保证了最基本的语法完整性,但可能丢失跨句的上下文。 段落级分块:按段落进行切分,这通常能更好地保留一个独立论点或描述的完整性。 章节级分块:对于结构清晰的科研论文,最有效的方法是根据标题(如”摘要”、”引言”、”方法”、”结果”、”讨论”)进行分层切分。这种方式不仅保证了宏观上下文的完整,也为后续的层级化检索策略(如RAPTOR)奠定了基础。 递归与层级化分块 (Recursive and Hierarchical Chunking) 更进一步,递归字符分割(Recursive Character Text Splitting)等方法试图在满足尺寸限制的同时,尽可能地保留文档结构。它会按照预设的分隔符优先级(例如,首先尝试按段落\n\n,然后是句子.,最后是空格)进行递归切分,直至块大小符合要求。 层级化分块(Hierarchical Chunking)则是一种更为结构化的方法。它首先将文档按大的逻辑单元(如论文的”方法”部分)进行划分,然后在这些大的单元内部再进行更细粒度的分块(如按段落或句子)。这种策略同时保留了文档的宏观结构和微观细节,为模型提供了多尺度的上下文信息。这种思想的演进,直接催生了如RAPTOR等更为复杂的树状索引结构。 1.2 多向量与多表征索引:增强语义丰富度 传统的RAG索引中,一个文本块对应一个向量。然而,单一向量往往难以捕捉一个知识片段的所有语义维度。多向量与多表征索引的核心思想是,为同一个文档块创建多个不同的向量表示,每个向量从一个独特的”视角”来捕捉其内容。这种方法将用于检索的向量与最终交付给LLM的原始内容解耦,从而实现更具针对性的搜索。 关键技术 摘要表征 (Summarization):为每个文本块(或整个文档)生成一个精炼的摘要,并对该摘要进行嵌入。当用户的查询更关注宏观主题而非具体细节时,基于摘要的检索会非常有效。例如,一个关于”FEP+AI在药物设计中的应用前景”的查询,更容易匹配到一个总结了整个研究方向的摘要,而不是某个描述具体算法步骤的文本块。 假设性问题 (Hypothetical Questions):对每个文本块,利用LLM生成若干个它可能回答的潜在问题。将这些问题嵌入并索引。当用户的查询与这些预生成的假设性问题相似时,系统就能精准地定位到能提供答案的原文。这极大地弥合了用户提问方式与文献陈述方式之间的差异。 关键词提取 (Keyword Extraction):如MC-indexing研究所提议的,从文本块中提取核心关键词,并将这些关键词列表作为一种独立的表征进行嵌入或索引。这种表征与传统的稀疏向量检索方法(如BM25)天然契合,能有效提升对专业术语的检索精度。 父文档检索 (Parent Document Retrieval / Small-to-Big Chunking):这是一项至关重要的技术。在索引阶段,系统将文档切分成非常小的、语义集中的块(例如单个句子或短段落)并进行嵌入。这些小块因其信息密度高,非常适合进行高精度的语义匹配。然而,在检索到这些小块后,系统并不直接将其交付给LLM,而是向上追溯,将包含该小块的、更大的”父文档”(如整个段落或完整的章节)作为上下文提供给LLM。这种”小块检索,大块生成”的策略,完美地平衡了检索的精准度与生成所需上下文的丰富度。 RAPTOR:递归摘要处理的树状索引 RAPTOR(Recursive Abstractive Processing for Tree-Organized Retrieval)代表了层级化索引思想的极致。该策略通过递归的方式,在整个文档语料上构建一个多层次的树状结构。其流程如下:首先,将所有文档分块;然后,对这些块进行聚类,并为每个聚类生成一个摘要;接着,再对这些生成的摘要进行聚类和摘要,如此递归,直至形成一个单一的根节点。最终,这个树状结构包含了从最底层的原始文本块到最高层的全局摘要等不同粒度的信息。在查询时,系统可以在树的不同层级上进行检索,既能找到具体的细节,也能理解文档集的宏观主题,极大地增强了对复杂信息需求的响应能力。 1.3 结构化非结构化数据:知识图谱驱动的索引 科研文献的本质并非孤立的文本片段,而是一个由实体(如蛋白质、配体、自由能变化值、FEP方法、AI算法)和它们之间复杂关系构成的知识网络。单纯的向量检索难以捕捉和利用这些显式的、事实性的结构化关系。知识图谱(Knowledge Graph, KG)为解决这一问题提供了强大的框架,它将非结构化的文本信息转化为结构化的图数据。 实体与关系自动抽取 (ERE) 构建知识图谱的第一步,是从”FEP+AI”文献语料中自动抽取实体及其关系。这需要借助先进的自然语言处理模型,通过流水线式(先识别实体,再分类关系)或联合学习(同时识别实体和关系)的方法,从文本中识别出关键实体(例如,[蛋白质-配体复合物]、[自由能计算方法]、[机器学习模型])并抽取出它们之间的关系(例如,(FEP方法)–[预测]–>(结合自由能)、(深度学习)–[优化]–>(采样效率))。这个过程将海量的非结构化文本转化为结构化的三元组 ⟨头实体, 关系, 尾实体⟩,为后续的图谱构建和查询奠定基础。 GraphRAG的实现 GraphRAG是一种革命性的方法论,它将知识图谱深度整合到RAG流程中。其核心流程如下: 图谱构建:首先,利用ERE技术处理整个文献库,构建一个领域专属的知识图谱。图中的节点代表实体,边代表它们之间的关系。 图谱查询:当用户提出一个复杂问题时,例如”机器学习如何改进FEP计算中的采样效率,从而提高自由能预测的准确性?”,系统不再是进行简单的向量搜索。取而代之的是,它会解析查询中的实体(”机器学习”、”FEP计算”、”采样效率”、”自由能预测”),并在知识图谱上执行图遍历或图查询。 多跳推理 (Multi-Hop Reasoning):通过在图谱中进行多步推理(例如,从”机器学习”出发,找到其应用的FEP方法,再找到这些方法改进的采样策略,最后找到这些策略如何影响自由能预测精度),系统能够整合来自多篇不同文献的信息,构建出一条完整的证据链。 上下文增强:最终,系统将图查询路径上的实体、关系以及它们关联的原始文本块一起作为上下文,提供给LLM。 GraphRAG的优势是巨大的。它能够回答需要综合多源信息的复杂问题,并且由于其答案基于可验证的图结构,因此具有极高的可解释性和溯源性(provenance),能有效抑制LLM的”幻觉”现象。 1.4 处理科学数据模态:解析表格、图表与分子结构 科研论文是典型的多模态文档,其中包含了大量信息密集的非文本元素,如承载实验数据的表格、阐释计算流程的图示以及关键的分子结构式。传统的文本解析工具(如PyPDF)在处理这些元素时常常力不从心,导致信息丢失或结构错乱,形成所谓的”解析炒蛋”(parsing scrambled eggs)。一个先进的RAG系统必须具备解析和理解这些多模态内容的能力。 先进的解析与抽取技术 表格抽取:利用unstructured.io、Camelot等库,或更先进的布局感知模型(如LayoutLM),可以将PDF中的表格解析为结构化格式(如Markdown、JSON或Pandas DataFrame)。一个关键的高级策略是,在解析出结构化表格后,利用LLM生成该表格的自然语言摘要,然后将摘要进行嵌入并索引,同时保留指向原始结构化数据的链接。这本质上是针对表格数据的”父文档检索”模式,既利用了摘要的语义可检索性,又保留了原始数据的完整性。 图表与图像抽取:对于图示和流程图,可以利用多模态大语言模型(MLLMs)或视觉语言模型(VLMs),如GPT-4V,为其生成详尽的文本描述或标题(caption)。这些生成的文本描述随后可以像普通文本一样被索引和检索,从而使视觉信息变得”可搜索”。 分子结构:在FEP+AI研究中,分子结构信息至关重要。这需要采用领域特定的前沿技术。例如,基于图神经网络的分子表示学习方法能够将分子结构编码为高维向量,这些向量可以与文本向量一起存储在统一的向量数据库中,实现跨模态的语义检索。 创建统一索引 最终目标是构建一个统一的多模态索引。在这个索引中,文本块、表格摘要、图表描述以及分子结构信息(可能以SMILES字符串或其描述的形式存在)都被表示为向量,并存储在同一个向量数据库中。每个向量都附有丰富的元数据,如来源文献、页码、原始数据类型(文本、表格、图像)等。这样的统一索引使得一次用户查询能够同时在所有模态的数据中进行检索,从而获得最全面、最相关的上下文。 在构建这个复杂的索引时,一个核心的架构考量浮现出来:索引阶段的复杂性与后续检索、后处理阶段的复杂性之间存在一种此消彼长的关系。采用简单的索引策略,如固定尺寸分块,会将压力完全转移到下游。系统将不得不依赖复杂的查询重写、混合搜索,特别是计算成本高昂的重排(re-ranking)模块,才能从充满噪声的候选中筛选出有用的信号。相反,如果前期投入巨大努力构建一个高度结构化的索引,例如通过GraphRAG或RAPTOR,将语义关系和层级结构直接编码到索引中,那么后续的检索任务就会变得相对简单,但前期的计算成本和系统复杂性会显著增加。对于FEP+AI这一知识密集型领域,实体间的关系至关重要且难以在检索时动态推断,因此,在索引阶段进行重投入,构建结构化、内容感知的索引,是更具长远价值的架构选择。 与此同时,行业内的讨论焦点正从单纯的”如何分块”(chunking)转向更深层次的”如何表征”(representation)。多向量索引和多模态技术的兴起标志着这一范式转变。目标不再仅仅是将文档分割成片,而是为同一信息片段创造多个、多样化的表征。一个段落可以同时拥有原始文本嵌入、摘要嵌入、假设性问题嵌入以及从中抽取的知识图谱三元组嵌入。这种多面体的表征方法构建了一个更丰富、更鲁棒的搜索界面,允许不同类型的查询通过不同的语义”棱镜”匹配到相同的底层内容。这也对向量数据库的模式(schema)设计提出了更高要求,需要从简单的 (id, vector, text) 结构演变为能够容纳和查询这些不同”视图”的多字段复杂结构。 第二部分:核心引擎——前沿的检索与查询增强技术 在构建了信息丰富的多维索引之后,系统的核心任务转变为如何精准地”触达”这些信息。这一阶段关注的是用户查询与索引之间的”接触点”,即如何深刻理解用户意图,并将其转化为高效、精准的检索指令。简单地将用户原始查询直接向量化并进行相似度搜索,往往是远远不够的。 2.1 检索前的查询转换 用户查询的原始形态往往是其信息需求的粗糙表达,可能充满歧义、术语不规范或过于简洁。因此,在执行检索之前对查询进行转换和增强,是提升检索命中率的关键第一步。 查询重写与扩展 (Query Rewriting and Expansion) 该技术利用LLM对原始查询进行优化。具体操作包括: 重写 (Rewriting):将口语化或模糊的查询改写为更正式、更明确的表述。例如,将”FEP+AI有什么好处”重写为”请阐述机器学习与自由能微扰计算结合在药物设计中的优势与应用前景”。 扩展 (Expansion):为查询补充同义词、相关术语或上位词,以扩大检索范围,避免因用词不一而错失相关文献。 分解 (Decomposition):将一个复杂的复合问题分解为多个更简单的子问题,然后对每个子问题分别进行检索,最后综合结果。 假设性文档嵌入 (HyDE) HyDE(Hypothetical Document Embeddings)是一种非常有效的弥合查询与文档之间语义鸿沟的技术。其核心逻辑是:用户的简短查询在语义上可能与详尽的答案文档相距甚远,但一个”理想的答案”在语义上会与真实的答案文档非常接近。因此,HyDE的流程是: 接收用户查询。 不进行检索,而是先让LLM根据其内部知识,生成一个针对该查询的、假设性的、理想的答案文档。这个文档可能包含虚构的细节,但其整体语义结构和关键概念是合理的。 对这个生成的假设性文档进行嵌入。 使用这个”答案”的嵌入向量,而不是原始查询的向量,去向量数据库中进行相似度搜索。 HyDE在零样本(zero-shot)检索场景下尤其强大,因为它不依赖任何标注数据就能有效地将查询的”意图”转化为与文档内容更匹配的语义表示。 “退一步”提示 (Step-Back Prompting) 对于需要深度推理的复杂问题,直接检索具体细节可能效果不佳。Step-Back Prompting技术通过引导LLM进行更高层次的抽象思考来解决这个问题。流程如下: 接收一个具体、细节化的问题,例如:”增强采样方法如何具体改进FEP计算中的构象空间探索效率?” 利用LLM,从原始问题生成一个更宏观、更根本的”退一步”问题,例如:”自由能计算中构象采样的基本原理和挑战是什么?” 系统同时对原始问题和”退一步”问题进行检索。 将两个问题检索到的文档(既包含具体细节,又包含基础原理)一并提供给生成模型。 这种方法通过补充基础性和原理性的上下文,极大地增强了LLM在回答复杂问题时的推理能力和答案的深度。 2.2 混合搜索架构 单一的检索模式往往存在局限性。最先进的RAG系统普遍采用混合搜索架构,结合多种检索范式的优势,以实现更鲁棒、更全面的信息召回。 稀疏与密集向量的融合 互补优势:密集向量(Dense Vectors),通常由BERT等深度模型生成,擅长捕捉文本的语义相似性。而稀疏向量(Sparse Vectors),如传统的BM25、TF-IDF或更现代的SPLADE模型,则精于关键词匹配,尤其对于那些在领域内至关重要的专有名词、缩写或ID(如蛋白质名、化合物编号)非常敏感。 实现方式:混合搜索系统会并行执行两种检索。首先,用户的查询会同时被送入密集向量编码器和稀疏向量编码器。然后,系统在向量数据库中同时进行语义相似度搜索和关键词搜索。最后,两路检索结果会通过一个融合算法(如倒数排序融合 Reciprocal Rank Fusion, RRF)进行合并和重排,得到最终的候选文档列表。这种架构确保了检索结果既在语义上相关,又不会遗漏包含关键术语的重要文献。 知识图谱与向量搜索的协同 这种架构将知识图谱的结构化推理能力与向量数据库的语义搜索能力相结合,是处理复杂关联性查询的利器。一个典型的协同工作流如下: 用户的查询首先通过向量搜索,在知识库中快速定位到相关的核心实体。例如,查询”AlphaFold2如何辅助FEP计算中的蛋白质构象预测”,向量搜索会首先找到”AlphaFold2”和”FEP计算”这些实体节点。 一旦定位到核心实体,系统就以此为起点,在知识图谱中进行图遍历。它可以沿着预定义的”预测”、”应用于”、”改进”等关系边,探索与”AlphaFold2”和”FEP计算”直接或间接相关的其他实体,如其输出的蛋白质结构、相关的采样方法、改进的自由能预测精度等。 这种多跳推理(multi-hop reasoning)能够发掘出单一向量搜索无法揭示的深层知识关联。最终,图遍历路径上的所有实体及其关联的文本证据,会共同构成一个结构化的、逻辑清晰的上下文,交付给LLM。 2.3 迭代与递归检索框架 传统的RAG流程是一次性的”检索-生成”过程。然而,对于需要综合多方面信息才能回答的复杂问题,单次检索往往是不够的。迭代和递归检索将RAG从一个静态的流水线,转变为一个动态、多步骤的探索过程。 迭代检索 (Iterative Retrieval) 迭代检索是一种循环反馈机制。系统首先根据原始查询进行一次初步检索,然后,LLM会分析这些初步结果,生成一个中间答案,或者更重要的是,识别出当前信息的不足之处和知识缺口。接着,LLM会基于这些新的认识,自主地生成一个或多个新的、更精确的查询,再次向检索器发出请求。这个”检索-分析-再查询”的循环会持续进行,直到系统判断已收集到足够的信息来完整回答最初的问题。这是构建智能体(Agentic)RAG系统的核心能力之一。 递归检索 (Recursive Retrieval) 递归检索特别适用于处理在索引阶段构建的层级化或关联性数据结构(如父文档、RAPTOR树、知识图谱关联节点)。其工作方式是:当检索器在顶层索引中命中一个”摘要”或”父”节点时,它不会就此停止,而是会根据该节点中包含的链接或引用,自动地、递归地去调用下一层的检索器或查询引擎,以获取更深层次的、更详细的信息。 例如,在一个关于某项关键实验的查询中,系统可能首先检索到一个总结该实验的摘要节点。递归检索机制会触发对与该节点关联的子节点的查询,从而自动取回关于该实验的详细”方法”描述、具体的”结果”数据表格,以及相关的”讨论”文本块。这样,一个看似简单的初步检索,就能”牵一发而动全身”,将一个完整实验的所有相关信息一网打尽,为LLM提供一个极其完整和连贯的上下文。 在这些先进的检索策略中,一个共同的趋势是,用户的原始查询正在从一个终点转变为一个起点。无论是HyDE、Step-Back Prompting还是查询重写,它们都将用户的输入视为一个待处理的信号,而不是最终的检索指令。系统需要先进行一番”思考”——生成假设、进行抽象、或是改写澄清——来创造出一个或多个更优的检索向量。这标志着RAG系统的”智能”正在向上游的查询理解阶段迁移,系统正从被动的”匹配”模式,演变为主动的”先推理,后匹配”模式。 同时,我们看到不同检索范式正在走向融合。纯粹的语义检索、纯粹的关键词检索或纯粹的图检索,都已无法满足复杂应用的需求。最前沿的系统本质上都是混合式的。稀疏-密集混合搜索承认了语义模型在处理关键术语时的不足;知识图谱-向量混合搜索弥补了向量空间无法表达显式逻辑关系的缺陷;而迭代检索则为这个静态的混合空间增加了时间的维度,将检索变成了一个动态演化的过程。因此,未来的SOTA架构必然是一个能够根据任务需求,动态编排和融合多种检索模式的、多模态、多范式的复杂系统。 第三部分:精炼层——后检索优化 经过前两个阶段,系统已经召回了一批与查询相关的候选文档。然而,这个候选集往往是”粗糙”的——它可能包含语义相关但实际无关的噪声,重要信息可能被淹没在次要内容之中,或者存在大量冗余信息。后检索优化阶段的目标,就是对这个粗糙的候选集进行”精炼”,确保最终传递给LLM的上下文是最高质量、最相关、最精炼的。 3.1 基于Cross-Encoder的高精度重排 Bi-Encoder vs. Cross-Encoder 理解重排(Re-ranking)的关键,在于区分两种不同的编码器架构: Bi-Encoder(双编码器):这是在初始检索阶段使用的模型。它为查询和每个文档独立地生成嵌入向量,然后通过计算这些向量之间的距离(如余弦相似度)来评估相关性。这种方式计算速度快,适合在大规模语料库上进行快速筛选,但由于查询和文档在编码时没有交互,其精度有限。 Cross-Encoder(交叉编码器):这是在重排阶段使用的模型。它将查询和单个文档拼接在一起,作为一个整体输入到Transformer模型中。这使得模型能够通过自注意力机制,在查询和文档的词元(token)之间进行深度的、细粒度的交互。最终,模型会输出一个单一的相关性分数(通常在0到1之间)。这种方式计算成本高昂,但由于充分捕捉了查询与文档之间的交互信息,其判断相关性的准确度远超Bi-Encoder。 两阶段检索流程 鉴于两种编码器的特性,业界最佳实践是采用一个两阶段的检索流程: 召回(Recall)阶段:使用快速的Bi-Encoder或混合搜索(如BM25+Bi-Encoder),从海量文档库中召回一个相对较大的候选集(例如,top 50或top 100)。这个阶段的目标是最大化召回率,即确保所有可能相关的文档都被包含在这个候选集内。 精排(Precision)阶段:使用计算密集但更准确的Cross-Encoder,对第一阶段召回的候选集进行逐一打分和重排序。然后,只选择得分最高的少数几个文档(例如,top 3或top 5)作为最终的上下文,传递给LLM。这个阶段的目标是最大化精确率,确保提供给LLM的信息质量。 模型选择与基准测试 选择合适的重排模型至关重要。对于科研文献这类专业领域,使用在相关语料(如生物医学文献)上预训练或微调过的模型,其效果会远超通用模型。评估重排模型性能时,可以参考学术界和工业界公认的基准测试集,如BEIR(Benchmarking Information Retrieval)和专为科学领域设计的新基准SciRerankBench。此外,一些研究也开始探索直接使用LLM本身作为重排器(例如,RankRAG),通过让LLM对候选文档进行排序。这种方法潜力巨大,但目前仍面临着显著的延迟和成本挑战。 3.2 上下文压缩与过滤 “迷失在中间”问题 LLM的上下文窗口长度是有限的,更重要的是,其在长上下文中的信息处理能力并非均匀分布。研究表明,当关键信息被放置在长篇上下文的中间部分时,LLM的注意力会下降,导致其”遗忘”或忽略这些信息,这种现象被称为”迷失在中间”(Lost in the Middle)。因此,后检索处理的一个核心目标就是提高上下文的”信噪比”,将最关键的信息以最醒目的方式呈现给LLM。 上下文压缩 (Contextual Compression) 上下文压缩是一种主动提纯上下文的技术。其基本流程是,在重排之后,系统会利用一个(通常是较小、较快的)LLM,遍历每个被选中的文档块,并根据原始用户查询,从中只抽取出最相关的句子或段落,丢弃其余的无关内容。通过这种方式,多个文档块中的核心信息被”压缩”成一个更短、信息密度更高的上下文,然后才被送入最终的生成模型。 过滤与元数据 (Filtering and Metadata) 除了压缩单个文档的内容,系统还可以根据元数据对整个文档块进行过滤。在索引阶段为每个块附加的元数据(如文献发表日期、作者、期刊、章节标题等)在此刻发挥了重要作用。系统可以根据查询的隐含需求(例如,用户可能更关心最新的研究进展)或显式指令,过滤掉不符合条件的文档块,例如只保留近两年发表的文献。 基于LLM的过滤 更高级的过滤技术会再次利用LLM的判断力。例如,LLMChainFilter等工具会让LLM对每个检索到的文档进行一次快速的”相关性检查”,直接丢弃那些虽然在向量空间中距离很近,但从上下文逻辑上看并不真正回答问题的文档。MAIN-RAG框架甚至提出了一种多智能体协作过滤机制,由多个LLM智能体共同对检索结果进行打分和筛选,以达成共识,确保只有最高质量的上下文被采纳。 整个先进的RAG流程,从架构上看,可以被理解为一个精心设计的概率漏斗。它的目标是通过一系列连续的步骤,逐步提高最终上下文的相关性概率。第一阶段的初始检索,是一个高召回、低精度的过程,它像一张大网,确保潜在的正确答案被捕获到候选集中。第二阶段的重排,则是一个高精度的筛选过程,它过滤掉了大部分明显的噪声。第三阶段的上下文压缩与过滤,则是最后的外科手术式精修,它精准地提取出最关键的句子,将最终提示词中的信息密度最大化。这种多级漏斗架构承认了任何单一环节都非完美,实现极致的精准是一个持续提纯和迭代的过程。 一个值得注意的趋势是,传统上被视为”生成”组件的LLM,正越来越多地被嵌入到”检索”流程的各个环节中。LLM现在被用于重排(RankRAG)、过滤(LLMChainFilter)和压缩(LLMChainExtractor)。这表明,RAG系统中”检索”与”生成”的界限正在变得模糊。取而代之的是一种新的架构范式:系统由多个、功能特化的LLM或模型级联而成。一些较小、较快的模型被部署在检索流水线内部,执行路由、过滤、排序等”推理”任务,其目的是为了优化和提纯上下文。而最终,这些经过精心准备的、高质量的上下文,才被交付给一个最强大的生成模型,以产出最终的答案。这预示着未来的RAG架构将更加模块化和异构化。 第四部分:系统综合——构建自适应的智能体RAG系统 综合前述的先进技术,我们可以将RAG系统从一个固定的、线性的处理流水线,演进为一个能够根据具体问题动态调整策略、甚至具备自主规划和反思能力的智能系统。这代表了RAG架构的最高形态:自适应(Adaptive)与智能体化(Agentic)。 4.1 自适应RAG:动态策略选择 核心理念 并非所有用户查询都具有相同的复杂性。一个简单的定义性问题(如”什么是自由能微扰?”)与一个复杂的综述性问题(如”总结近十年来AI在FEP计算中的应用进展及其对药物设计的影响”)所需的处理策略截然不同。自适应RAG的核心思想是,在处理流程的起点引入一个”查询分析器”(通常由一个小型LLM担任),由它来判断查询的类型和复杂性,并动态地将查询路由到最合适的处理路径上。 潜在的路由路径 根据查询分析的结果,系统可以选择多种执行策略: 无检索:对于常识性或LLM参数化知识范围内的问题,直接由LLM生成答案,避免不必要的检索开销。 简单检索:对于事实查询,执行一次标准的”检索-重排-生成”流程。 多步/迭代检索:对于需要综合多方面信息的复杂问题,启动迭代检索循环,分解问题并进行多次查询。 Web搜索:对于涉及最新事件或知识库中未包含的信息的查询,调用外部搜索引擎API。 实现方式 这种动态路由机制通常通过状态机或计算图(Graph)的范式来实现。使用LangGraph等框架,开发者可以定义一系列的”节点”(Nodes),每个节点代表一个操作(如检索、打分、生成)。节点之间的”边”(Edges)则代表了由LLM路由器做出的决策,从而构建出一个灵活、可根据输入动态改变执行路径的复杂工作流。 4.2 智能体RAG:自主的检索工作流 智能体的飞跃 如果说自适应RAG是让系统学会”选择”预设的路径,那么智能体RAG(Agentic RAG)则是让系统具备了”规划”全新路径的能力。它将整个RAG系统提升为一个自主的智能体,而检索只是它可用的众多”工具”(Tools)之一。这个智能体能够进行规划、执行一系列动作,并根据外部反馈进行自我修正。 典型的智能体工作流 一个典型的智能体RAG工作流可能包含以下步骤: 分解与规划 (Decomposition & Planning):接收到复杂任务后,智能体首先将其分解为一个多步骤的执行计划。 工具选择 (Tool Selection):对于计划中的每一步,智能体自主决定使用哪种工具。工具箱可以非常丰富,包括:向量数据库检索、知识图谱遍历、Web搜索、代码解释器(用于计算)、数据库查询等。 迭代检索与反思 (Iterative Retrieval & Refinement):智能体执行一个工具(例如,进行一次向量搜索),并”观察”返回的结果。然后,它会进行自我反思:这些信息是否足够?是否相关?如果答案是否定的,它可以决定改写查询、更换工具,然后再次尝试。这个”行动-观察-反思”的循环是智能体RAG的核心,赋予了它强大的自我校正和深度探索能力。 综合生成 (Synthesis):当智能体判断已收集到足够的信息后,它会综合所有步骤中获得的信息,生成最终的、通常附带详细推理过程的答案。 4.3 面向FEP+AI研究的架构蓝图 结合本报告讨论的所有先进技术,以下为一个专为”FEP+AI”科研文献库量身定制的、综合了自适应与智能体思想的RAG系统架构蓝图。 数据注入流水线 (Ingestion Pipeline) 多模态解析:使用unstructured.io或NVIDIA NeMo Retriever等先进的文档解析工具,从PDF中同时抽取出文本、表格和图表。 知识图谱构建:利用在科学文本上微调的联合实体关系抽取模型,自动构建一个包含分子、蛋白质、FEP方法、AI算法、自由能值等实体及其关系的知识图谱。 内容感知分块:严格按照科研论文的章节结构(摘要、引言、方法、结果等)对文本进行分块。 多向量索引创建:在向量数据库中,为每个信息单元创建多重表征: 原始文本块的嵌入(使用SciBERT等领域专用模型)。 由LLM生成的每个文本块的摘要嵌入。 从文本中抽取的知识图谱实体的嵌入。 由VLM生成的图表标题和详细描述的嵌入。 推理流水线 (Inference Pipeline) - 自适应与智能体化 查询路由器 (自适应RAG):一个小型LLM首先对用户查询进行分类,判断其复杂度和意图。 查询转换:根据查询类型,动态应用最优的转换策略。对于”为什么/如何”类问题,采用Step-Back Prompting;对于”是什么”类问题,采用HyDE。生成多个待检索的查询向量。 混合检索:并行执行多种检索模式: 在文本和摘要嵌入上进行密集向量搜索。 使用BM25进行稀疏向量搜索,以匹配精确的方法名称和技术术语。 从查询中识别出的实体开始,在知识图谱中进行图遍历。 初步融合与重排:使用RRF算法融合三路检索结果,然后用一个高性能的Cross-Encoder(如BGE-reranker)对前100个候选结果进行高精度重排。 智能体自我校正循环:一个LLM智能体审查重排后的顶尖结果。 相关性评估:顶部的文档是否真的相关?如果不相关,智能体可以决定重写查询,并返回第2步。 完整性检查:当前信息是否足以回答问题?如果判断出这是一个需要多步推理的复杂问题,智能体会识别出下一个需要查询的实体或概念,并启动新一轮的迭代检索。 上下文压缩与最终提示词构建:当智能体对收集到的信息感到满意时,调用一个LLM对最终的文档集进行上下文压缩,只提取最核心的句子。然后,将这些精炼后的上下文、原始查询以及可能的推理链条,组装成最终的提示词。 生成:将这个信息密度极高的提示词,提交给最强大的生成模型(如GPT-4系列、Claude 3系列),生成最终的、有理有据、并附带引文的答案。 先进RAG技术对比分析 为了在架构设计中做出明智的权衡,下表对本报告中讨论的最具影响力的几种技术进行了战略性比较。 技术 主要优势 主要局限 适用场景 实现复杂度 RAPTOR 多层级信息检索,支持宏观和微观问题 构建成本高,需要大量预处理 大规模文档库,需要不同粒度信息的查询 高 GraphRAG 多跳推理,可解释性强,抑制幻觉 实体关系抽取质量依赖,图构建复杂 知识密集型领域,需要关联推理 高 HyDE 零样本效果好,弥合查询-文档语义鸿沟 生成假设文档可能偏离真实需求 查询与文档表达方式差异大的场景 中 Cross-Encoder重排 精度显著提升,考虑查询-文档交互 计算成本高,只能用于少量候选 所有需要高精度的RAG系统 低 混合搜索 结合语义和关键词匹配优势 融合策略需要调优,复杂度增加 专业术语重要的科研领域 中 智能体RAG 自主规划,自我校正,处理复杂问题 成本高,延迟大,可控性降低 复杂推理任务,多步骤信息整合 高 结论 构建一个能够精准服务于”FEP+AI”等前沿科研领域的RAG系统,是一项超越基础流程的复杂工程。本报告的深度调研表明,实现从”搜得到”到”搜得准”的质的飞跃,依赖于一个系统性的、贯穿整个RAG生命周期的优化哲学。 成功的架构必须始于一个精心设计的索引基础。放弃简单粗暴的固定尺寸分块,转向内容感知和层级化的切分策略,是保留科研文献上下文完整性的第一步。更进一步,通过多向量表征、父文档检索乃至RAPTOR等技术,可以为同一知识片段构建多维度的语义入口。而对于科学知识的内在结构性,引入知识图谱(GraphRAG),将非结构化文本转化为可进行多跳推理的结构化知识,是解锁深层次、关联性问题答案的关键。同时,必须正视科研文献的多模态特性,集成先进的解析工具来处理表格、图表和分子结构,构建一个统一的、跨模态的知识索引。 在强大的索引之上,需要一个智能的检索核心。用户的原始查询应被视为一个起点,而非终点。通过查询重写、HyDE和”退一步”提示等技术,系统能够主动推理用户意图,生成更优的检索指令。结合稀疏与密集向量的混合搜索以及知识图谱的协同查询,能够确保检索的广度与深度。而迭代与递归检索框架则将静态的单次查询,转变为动态的、探索式的知识发现过程。 最后,一个严格的精炼层是保证最终答案质量的”守门员”。通过Cross-Encoder进行高精度重排,可以从大量召回结果中筛选出最相关的少数。再通过上下文压缩与过滤,剔除噪声,最大化LLM上下文窗口内的信噪比,从而有效规避”迷失在中间”的问题。 综合来看,最前沿的RAG系统正在向自适应和智能体化的方向演进。系统不再是固定的流水线,而是能够根据查询的复杂性动态选择最优策略,甚至能够像一个自主的研究助理一样,进行多步规划、工具调用和自我修正。为”FEP+AI”领域构建的终极RAG系统,应当是一个融合了上述所有先进技术的、高度集成化的智能体架构。虽然其实现复杂度和计算成本高昂,但这正是从根本上解决检索精度瓶颈、构建真正可靠和智能的科研知识引擎所必须付出的投资。
Techniques
· 2025-10-08
【笔记整理|2024-07】高性能分子动力学模拟优化策略:GPU并行与多节点配置详解
【笔记整理|2024-07】高性能分子动力学模拟优化策略:GPU并行与多节点配置详解 引言 分子动力学模拟是计算化学和生物物理学中的重要工具,随着系统规模的扩大和计算精度的提高,对计算资源的需求也越来越大。本文整理了从QQ技术讨论中提取的关于GROMACS分子动力学模拟性能优化的关键技术和实践经验,重点关注GPU并行计算、多节点配置和性能调优策略。 GPU优化与并行计算 多GPU配置策略 在使用多个GPU进行分子动力学模拟时,性能优化需要考虑通信开销和计算效率的平衡: As before, the scaling when going from one GPU to two is not linear. This is expected: GPUs now don’t have as much to compute and they have to communicate between each other. To add to that, the communications can not be easily hidden behind the computations. To make the best use of the resources, ensemble runs can be executed. Try to use multi-dir approach as we did before, to see what configuration will give you the best cumulative performance. Try to assign more than one rank to a single GPU. This will allow to overlap communications, CPU and GPU execution more efficiently. Try to leave bonded computation and/or update constraints to the CPU: you have 10 CPU core per single GPU and it would be a waste to keep them idle. 多GPU配置示例: Run GROMACS using 4 GPUs (with IDs 0,1,2,3). Here we use 2 thread-MPI tasks per GPU (-ntmpi 8), which we find gives good performance. We set 16 OpenMP threads per thread-MPI task (assuming at least 128 CPU cores in the system). These can be adjusted to map to any specific hardware system, and experimented with for best performance… 动态负载平衡 动态负载平衡是GROMACS中的一个重要优化特性: 动态负载平衡默认开启(-dlb auto),可显式指定 -dlb yes,以在粒子分布不均或相互作用强度不同的情况下动态调整域大小。需要注意的是,在GPU常驻模式(使用-update gpu)时,动态负载平衡会被关闭 PME性能调优 PME(Particle Mesh Ewald)方法是计算长程静电相互作用的重要算法,GROMACS提供了自动调优功能: The PME tuning is on by default whenever it is likely to be useful, can be forced on with gmx mdrun -tunepme, and forced off with gmx mdrun -notunepme. In practice, mdrun does such tuning in the first few thousand steps, and then uses the result of the optimization for the remaining time. Given that GROMACS already had a fast CPU implementation, moving the biggest workload to the GPU provides the best parallelism. 温度控制与采样策略 高温增强采样 在分子动力学模拟中,提高温度可以增强构象采样效率: High temperatures increase the kinetic energy but do not directly alter the nonbonded interaction parameters (e.g., van der Waals forces, electrostatics) defined by the force field. The force field parameters remain consistent, meaning the fundamental interactions governing molecular behavior are not artificially distorted by temperature alone. High temperatures increase the kinetic energy of the system, allowing it to overcome energy barriers and explore a broader conformational space. 温度对构象采样的影响: try a 1000K protein to make it denature The simulations at 500 and 800 K both generated conformations that minimized to energies 200 kcal/mole lower than the crystal structure. However, the 1500 K simulation produced higher energy structures, even after minimization; in addition, this highest temperature run had many cis-trans peptide isomerizations. This suggests that 1500 K is too high a temperature for unconstrained conformational sampling. 退火策略 退火是一种通过逐渐改变系统温度来优化构象的技术: The annealing is implemented by simply changing the current reference temperature for each group in the temperature coupling, so the actual relaxation and coupling properties depends on the type of thermostat you use and how hard you are coupling it. 距离计算与相互作用分析 距离计算工具 GROMACS提供了多种距离计算工具用于分析分子间相互作用: gmx distance -s 2beg_pull.tpr -f 2beg_pull.xtc -n protein.ndx -oall 2beg_pull_dist.xvg -select ‘com of group “Chain_A” plus com of group “Chain_B”’ gmx mindist computes the distance between one group and a number of other groups. Both the minimum distance (between any pair of atoms from the respective groups) and the number of contacts within a given distance are written to two separate output files. 注意事项: gmx distance expects the selections to have an even number of positions, meaning pairs of atoms to calculate the distances between. -select ‘com of group “first” plus com of group “last”’: This command calculates the center of mass (COM) of the group first and last and the distance between these centers. 径向分布函数(RDF)计算 径向分布函数是研究液体结构和分子间相互作用的重要工具: To compute the RDF around axes parallel to the z-axis, i.e., only in the x-y plane, use -xy. 软核相互作用与自由能计算 软核势能函数 在自由能计算中,软核相互作用用于避免粒子消失时的奇点问题: Direction-periodic should only be used for cases where you want to pull over distances of more than half the box length. Such cases are very uncommon. Pulling a large polymer could be a valid use case. With an NVT simulation things should be fine. But you probably want to pull to a distance of slightly less than the full box size to avoid interactions between periodic images. 软核相互作用的详细信息: https://manual.gromacs.org/current/reference-manual/functions/free-energy-interactions.html#soft-core-interactions-beutler-et-al 构建辅助工具与拓扑处理 psfgen构建工具 VMD的psfgen是一个强大的分子拓扑构建工具,但也存在一些需要注意的问题: vmd modeling is stupid: residue 5 is a normal residue that contains BOND C +N, while residue 6 does not include N (but NC) atom. so vmd creates a bond between residue 5 C and the last atom (PHE HE2B)??? how to fix? it depends on the residue pair: it seems to try to use the coordinates of existing atoms (residue before mutation), and apply IC for the rest. the most common error is a misreplacement (exchange) of C and H connected to the same Carbon (while the Hs on the C might be right or wrong…). sometimes only terminal Hs are wrong (centered on another atom?) I still don’ t know why 内坐标与拓扑生成 在内坐标(IC)生成过程中,需要注意键角和二面角的自动生成: Both angles and dihedrals are generated automatically unless “auto none” is added 36 1 makes vmd output “psfgen) Created by CHARMM version 36 1” 资源管理与作业调度 SLURM作业管理 在使用SLURM作业调度系统时,合理配置资源请求和节点选择非常重要: #SBATCH –exclude=node4,node5,node7,node8,node9 we can only specify one for –nodelist, but #SBATCH –exclude=node[1-16] works 作业提交与管理: https://bioinformaticsworkbook.org/Appendix/HPC/SLURM/submitting-dependency-jobs-using-slurm.html#gsc.tab=0 性能监控与调试 GPU利用率监控 监控GPU使用情况对于性能优化非常重要: https://stackoverflow.com/questions/40937894/nvidia-smi-volatile-gpu-utilization-explanation GROMACS性能调试 通过分析GROMACS的输出信息可以了解性能瓶颈: Note the following line in the gmx mdrun output: 总结与建议 多GPU配置:合理配置GPU数量和CPU核心分配,平衡计算和通信开销 动态负载平衡:在非GPU常驻模式下启用动态负载平衡以优化性能 温度控制:根据具体研究需求选择合适的温度策略,高温有助于构象采样但可能破坏蛋白质结构 距离分析:熟练使用gmx distance和gmx mindist等工具进行分子间相互作用分析 拓扑构建:注意VMD建模中的常见问题,合理设置内坐标生成参数 资源管理:合理配置SLURM作业参数,优化计算资源使用 通过这些优化策略,可以显著提高分子动力学模拟的计算效率和结果的准确性。 参考资源 GROMACS GPU性能优化指南 GROMACS多GPU使用论坛讨论 GROMACS官方文档 SLURM依赖作业提交指南 NVIDIA SMI利用率解释
Techniques
· 2025-10-08
【笔记整理|2024年上半年】Python数据分析与可视化技术指南
【笔记整理|2024年上半年】Python数据分析与可视化技术指南 本文汇总了在科研数据分析中使用Python的实用技巧,涵盖数据处理、可视化、性能分析等核心技术。 NumPy和SciPy数据处理 数组操作和统计分析 寻找数组中的局部极值 使用scipy.signal.argrelextrema函数寻找一维数组中的相对极值(最大值和最小值): import numpy as np from scipy.signal import argrelextrema from scipy.stats import gaussian_kde # 示例:寻找密度函数的局部最小值 data = np.array([...]) # 你的数据 density = gaussian_kde(data) x = np.linspace(data.min(), data.max(), 1000) y = density(x) # 寻找局部最小值 minima_indices = argrelextrema(y, np.less) minima = x[minima_indices] 注意:argrelextrema函数寻找y是局部最小值的索引(即小于其邻居的点)。 数组处理常见问题 # 处理数组转换失败的问题 # "cannot process into arrays" 错误通常是由于数据类型不一致 try: arr1 = np.array(str1.split()) result = np.array([float(x) for x in arr1]) except ValueError as e: print(f"Array conversion failed: {e}") 数据可视化 Matplotlib配置和使用 基础导入和配置 import matplotlib.pyplot as plt import matplotlib # 获取matplotlib缓存目录 cache_dir = matplotlib.get_cachedir() print(f"Matplotlib cache directory: {cache_dir}") 字体和缓存问题解决 import os import matplotlib # 清理matplotlib字体缓存 font_directory = os.path.join(matplotlib.get_data_path(), 'fonts', 'ttf') # 如果遇到字体问题,删除缓存重新生成 # rm -r /home/username/.cache/matplotlib Seaborn可视化技巧 Violin Plot使用和问题解决 import seaborn as sns import matplotlib.pyplot as plt # 创建violin plot sns.violinplot(data=data) # 常见问题:分布显示为负值(但数据全为正) # 解决方案:使用内核密度估计的截断参数 sns.violinplot(data=data, cut=0) # cut=0避免扩展到数据范围之外 问题说明:使用sns.violinplot时发现某些分布低于0,但数据全为正值。这是因为核密度估计默认会在数据范围外进行插值。 Violin Plot进阶用法 Violin Plot数据分析指南:https://www.geeksforgeeks.org/violin-plot-for-data-analysis/ 分组柱状图制作 多种方法实现分组柱状图 当数据格式为矩阵时,创建分组柱状图的5种方法: import matplotlib.pyplot as plt import numpy as np import pandas as pd # 方法1:使用matplotlib def method1_matplotlib(data_matrix): x = np.arange(len(data_matrix)) width = 0.35 fig, ax = plt.subplots() for i in range(data_matrix.shape[1]): ax.bar(x + i*width, data_matrix[:, i], width, label=f'Group {i+1}') ax.legend() # 方法2:使用pandas def method2_pandas(data_matrix): df = pd.DataFrame(data_matrix) df.plot(kind='bar', ax=plt.gca()) # 方法3:使用seaborn def method3_seaborn(data_matrix): df = pd.DataFrame(data_matrix) df_melted = df.melt() sns.barplot(data=df_melted, x='variable', y='value') # 其他方法可参考plotnine等工具 Pandas数据操作 基础数据处理 import pandas as pd # 基本数据导入和处理 df = pd.read_csv('data.csv') 数据结构操作 字典排序 # 按键对字典进行排序 mydict = {'c': 3, 'a': 1, 'b': 2} sorted_mydict = dict(sorted(mydict.items(), key=lambda item: item[0])) Python字典排序指南:https://www.golinuxcloud.com/python-sort-dictionary-by-key/ 性能分析与优化 代码性能分析 cProfile性能分析 在Python中,可以使用cProfile模块来分析每个函数的执行时间: import cProfile cProfile.run('your_function()') 不同运行环境性能对比 实际测试发现: PyCharm profile:71秒 简单debug模式:56秒 命令行直接运行:31秒 性能分析显示主要耗时操作: fit操作:约8秒 concat操作:6秒 process_dict:11.6秒 算法复杂度理解 Python排序算法 Python内置的sorted()函数使用双轴快排算法(timsort),时间复杂度: 最坏情况:O(n * log n) 平均情况:O(n * log n) W3Schools Python sorted()函数:https://www.w3schools.com/python/ref_func_sorted.asp 哈希表查找效率 集合和字典在Python中都通过哈希表实现,元素查找时间复杂度通常为O(1),这使得元素位置可以快速定位。 高阶函数与函数式编程 函数套用(高阶函数) 在Python中,函数可以套用函数,这是一种常见的编程模式,也被称为高阶函数。这意味着一个函数可以接受另一个函数作为参数,或者返回一个函数作为结果。 动态属性设置 # 使用setattr动态设置对象属性 setattr(obj, 'attribute_name', value) # __getattr__方法在访问不存在的属性时被调用 def __getattr__(self, name): # 处理不存在的属性访问 pass 图论和网络分析 节点连接分析 处理图中节点组之间的连接问题: # 问题:找到连接两个节点组的节点对 # 可能每个节点组对有一个节点对连接 # 解决思路:构建二分图可能有助于快速找到这些连接 def find_connecting_pairs(graph, group1, group2): """ 找到连接两个节点组的节点对 考虑使用二分图表示来优化搜索 """ connecting_pairs = [] for node1 in group1: for node2 in group2: if graph.has_edge(node1, node2): connecting_pairs.append((node1, node2)) return connecting_pairs 列表元素计数 # 统计列表中元素出现次数的多种方法 from collections import Counter # 方法1:使用Counter my_list = [1, 2, 2, 3, 3, 3] counts = Counter(my_list) Python列表元素计数方法:https://datagy.io/python-count-occurrences-in-list/ 组合与迭代 列表组合生成 import itertools # 获取两个列表的所有唯一组合 combinations = list(itertools.product(list1, list2)) Python组合生成教程:https://www.geeksforgeeks.org/python-program-to-get-all-unique-combinations-of-two-lists/ 迭代中修改集合 # 错误示例:迭代过程中修改集合大小 RuntimeError: Set changed size during iteration 避免在迭代过程中修改正在迭代的集合。 科研数据处理最佳实践 数据验证 def validate_data(data): """验证科研数据的基本检查""" # 检查数据范围合理性 if np.any(data < 0) and data_should_be_positive: print("Warning: Found negative values in positive-only data") # 检查缺失值 if np.any(np.isnan(data)): print("Warning: Found NaN values") # 检查异常值 q1, q3 = np.percentile(data, [25, 75]) iqr = q3 - q1 outliers = (data < q1 - 1.5*iqr) | (data > q3 + 1.5*iqr) if np.any(outliers): print(f"Warning: Found {np.sum(outliers)} potential outliers") 可重现性保证 # 设置随机种子确保结果可重现 np.random.seed(42) # 保存分析环境信息 def save_environment_info(): import sys import numpy import matplotlib import pandas env_info = { 'python_version': sys.version, 'numpy_version': numpy.__version__, 'matplotlib_version': matplotlib.__version__, 'pandas_version': pandas.__version__ } return env_info 大数据处理 # 处理大型数组时的内存优化 def process_large_array(data, chunk_size=1000): """分块处理大型数组""" results = [] for i in range(0, len(data), chunk_size): chunk = data[i:i+chunk_size] processed_chunk = process_chunk(chunk) results.append(processed_chunk) return np.concatenate(results) 向量化计算 # 优先使用NumPy向量化操作而非Python循环 # 低效方式 def slow_calculation(data): results = [] for x in data: results.append(x**2 + 2*x + 1) return results # 高效方式 def fast_calculation(data): return data**2 + 2*data + 1 第三方库和工具 Plotnine使用 # plotnine相关问题和解决方案 Plotnine GitHub问题:https://github.com/has2k1/plotnine/issues/79 plotnine是Python中ggplot2的实现,适合熟悉R语法的用户。 调试和故障排除 常见错误模式 数组转换失败:通常由数据类型不一致造成 可视化异常值:密度估计超出数据范围 内存不足:大数据集处理时的常见问题 迭代修改错误:在迭代过程中修改集合 调试建议 使用print()语句检查中间结果 利用Jupyter notebook的交互式特性 保存关键步骤的中间数据 记录完整的软件环境信息 本文基于2023年9月至2024年上半年的技术实践整理,涵盖Python数据分析和可视化的核心技术要点
Techniques
· 2025-10-07
【笔记整理|2023-09】Linux科研开发环境配置和管理指南
【笔记整理|2023-09】Linux科研开发环境配置和管理指南 本文总结了在Linux环境下进行科研开发的实用配置技巧、常见问题解决方案和工具推荐。 跨平台文件同步和远程控制 KDE Connect:跨设备无缝协作 功能特色 KDE Connect是一个强大的跨平台设备协作工具,支持Windows、Linux、macOS、iOS、Android之间的无缝连接: # 安装KDE Connect sudo apt install kdeconnect # Ubuntu/Debian sudo dnf install kdeconnect # Fedora 主要功能 KDE Connect虽然不是投屏软件,但功能非常丰富: 文件传输: 电脑文件右键直接发送至手机 手机图片视频可发送到电脑指定文件夹 无需蓝牙,只要在同一局域网即可 远程控制: 手机作为电脑遥控器 音乐视频播放控制(音量、进度、暂停等) PPT演示时手机可作为翻页器 通知同步: 手机电话、短信通知同步到电脑 在电脑上让手机发出声音找手机 剪贴板共享: 跨设备剪贴板同步 复制粘贴无缝衔接 命令执行: 预设Linux命令,手机远程执行 支持关机、锁屏、自定义脚本等 远程桌面解决方案对比 ToDesk 官网:ToDesk Linux版:https://www.todesk.com/linux.html 优点:免费,跨平台支持好 缺点: Linux不支持复制粘贴功能 任务栏显示问题(特别是全屏模式) 输入法切换可能有问题 AnyDesk 安装和配置: # 禁用自启动 # 参考:[AnyDesk禁用自启动指南](https://devicetests.com/disable-anydesk-autostart-ubuntu):https://devicetests.com/disable-anydesk-autostart-ubuntu # 会话管理 # 参考:[AnyDesk会话管理](https://support.anydesk.com/knowledge/disconnecting-sessions):https://support.anydesk.com/knowledge/disconnecting-sessions Fedora安装问题:Fedora论坛讨论:https://discussion.fedoraproject.org/t/cannot-install-anydesk/73854 代理和网络配置 代理软件配置 electron-ssr配置 # 启动命令(解决沙盒问题) /usr/bin/electron-ssr --no-sandbox # Fedora38环境下使用 # electron-ssr在conda环境中不会报错 相关问题讨论:Electron-SSR GitHub问题:https://github.com/shadowsocksrr/electron-ssr/issues/126 Clash for Windows Linux版 配置指南:Linux Clash配置教程:https://bestoko.cc/p/linux-clash-for-windows/ 其他代理工具 go-proxy-bingai设置:GitHub项目:https://github.com/adams549659584/go-proxy-bingai 网络连接问题诊断 Fedora镜像源问题 # 常见错误:无法连接到Fedora镜像源 Failed to search for file: cannot update repo 'fedora': Cannot prepare internal mirrorlist: Curl error (7): Couldn't connect to server for https://mirrors.fedoraproject.org/metalink?repo=fedora-38&arch=x86_64 [Failed to connect to 127.0.0.1 port 12333 after 0 ms: Couldn't connect to server] 解决方案: 检查代理设置是否正确 尝试更换镜像源 检查防火墙和网络配置 开发工具配置 Visual Studio Code 扩展开发 # VSCode扩展路径 /home/user/.vscode/extensions/md-highlighter-0.0.1 # 发布token配置 vscode token: your_token_here 已知问题 虚拟桌面恢复:VSCode或Firefox无法在Fedora KDE中将窗口恢复到正确的虚拟桌面,这是已知问题 调试配置:缺少.vscode文件夹可能导致调试扩展无法识别 相关讨论:VSCode VSCE GitHub问题:https://github.com/microsoft/vscode-vsce/issues/419 Linux原生应用 微信支持 现在优麒麟下有Linux原生的微信,虽然功能简陋了一些, 但是有比没有强,基本的聊天需求是可以被满足的。 文件权限管理 # 设置可执行权限 chmod +x /path/to/Multiwfn_3.8_dev_bin_Linux/Multiwfn # 批量权限设置 find . -type f -exec chmod a+x {} \; 系统优化和故障排除 桌面环境配置 KDE Plasma优化 启动速度:Plasma启动需要25-40秒(可能与NVIDIA显卡有关) 应用启动器:左下角的”f”图标(Plasma application launchers) 窗口恢复:重启后只有Firefox能够恢复窗口状态 虚拟桌面管理 目前VSCode和Firefox在Fedora KDE中无法正确恢复虚拟桌面窗口位置。 编译工具链配置 Devtoolset(CentOS/RHEL) Devtoolset是一个用于在Red Hat Enterprise Linux (RHEL)和CentOS系统上 安装和使用多个版本的编译器和开发工具的软件集合。 它提供了更新的编译器版本,以便开发人员可以使用最新的功能和优化。 包管理问题 # Conda包损坏问题 InvalidArchiveError("Error with archive /home/user/anaconda3/pkgs/gxx_impl_linux-64-10.4.0-h7ee1905_16.tar.bz2. You probably need to delete and re-download or re-create this file.") # 解决方案:清理并重新下载 conda clean -a 端口和服务管理 端口占用检查 # 查看端口12333的使用情况 sudo lsof -i :12333 # 识别占用端口的进程 lsof -i :port_number 系统服务管理 # 检查系统版本 gnome-shell --version # 网络服务诊断 ping -c 4 mirrors.fedoraproject.org 文档和教程资源 Bash编程 Bash序列表达式:https://linuxize.com/post/bash-sequence-expression/ Python字典排序:https://www.golinuxcloud.com/python-sort-dictionary-by-key/ 网络分析工具 import networkx as nx NetworkX文档:NetworkX算法文档:https://networkx.org/documentation/stable/reference/algorithms/traversal.html Ubuntu系统资源 Amber22安装指南:http://archive.ambermd.org/202302/att-0090/Amber_22_and_Tools_22_install_Ubuntu_22.pdf 性能优化建议 GPU计算支持 配置GPU支持的计算环境: Quick package for Hartree-Fock and DFT electronic stucture calculations, with GPU support. Quick is integrated into sander for QM/MM simulations, and AmberTools23 contains significant performance improvements, a new geometry optimizer, and support for spin-unrestricted calculations. 跨平台兼容性 注意Linux和Windows之间文件格式的兼容性: 是因为在Linux里面读Windows的chk? 某些二进制文件在不同操作系统间可能存在兼容性问题。 故障排除检查清单 网络连接问题 检查代理设置 electron-ssr是否正常运行 端口12333是否被占用 防火墙设置是否正确 包管理问题 conda缓存是否损坏 镜像源是否可访问 网络连接是否稳定 桌面环境问题 显示相关 NVIDIA驱动是否正确安装 Plasma启动时间是否异常 虚拟桌面功能是否正常 应用兼容性 VSCode扩展是否正确安装 .vscode配置文件夹是否存在 权限设置是否正确 开发环境问题 编译工具 GCC版本是否兼容 开发库是否完整安装 环境变量是否正确设置 Python环境 conda环境是否激活 包依赖是否满足 路径配置是否正确 推荐的Linux发行版选择 科研用途推荐 Ubuntu LTS:稳定性好,社区支持强 Fedora:新技术支持好,适合开发 优麒麟:中文支持好,有原生微信 桌面环境选择 KDE Plasma:功能丰富,可定制性强 GNOME:简洁美观,资源占用相对较低 本文基于2023年9-12月技术讨论记录整理,涵盖Linux环境下科研开发的实际经验和解决方案
Techniques
· 2025-10-07
Deploy PostgreSQL Database and MinIO Object Storage: Complete Server Setup Guide
Ubuntu 22.04 服务器部署 PostgreSQL 数据库、MinIO 对象存储以及一个通过 Nginx 反向代理访问的 Docker化 Django 后端应用完整教程 目标: 部署 PostgreSQL 数据库、MinIO 对象存储以及一个通过 Nginx 反向代理访问的 Docker化 Django 后端应用。 服务器 IP 定义 (请在脚本和配置中替换为您真实的服务器 IP): SERVER_IP="123.45.6.78" (示例 IP,请务必修改) 第 1 步:系统初始化与基础依赖安装 首先,更新您的服务器并安装一些必要的工具。 # 更新系统包列表并升级现有包 sudo apt update && sudo apt upgrade -y # 安装基础工具:ca-certificates, curl, gnupg, lsb-release 用于添加 Docker源,nginx 用于反向代理,git 用于拉取代码 sudo apt install -y ca-certificates curl gnupg lsb-release nginx git 第 2 步:安装 Docker CE 和 Docker Compose 我们将使用 Docker 来容器化 MinIO 和 Django 应用。 # 1. 添加 Docker 官方 GPG 密钥 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg # 2. 设置 Docker APT 软件源 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 3. 安装 Docker CE (社区版), CLI, Containerd, 和 Docker Compose 插件 sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 4. (可选)配置国内 Docker 镜像加速器,以提高拉取镜像的速度 # 请根据您选择的云服务商或镜像源替换下面的地址 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<EOF { "registry-mirrors": [ "https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com", "https://registry.docker-cn.com" ] } EOF sudo systemctl daemon-reload sudo systemctl restart docker # 5. 将当前用户添加到 docker 组,这样执行 docker 命令时无需 sudo(需要重新登录或执行 newgrp docker 生效) sudo usermod -aG docker $USER echo "请重新登录或执行 'newgrp docker' 使 docker 组权限生效。" # 6. 验证 Docker 是否安装成功 docker --version docker compose version 第 3 步:安装 PostgreSQL 并配置远程访问 Django 应用将使用 PostgreSQL作为数据库。 # 1. 安装 PostgreSQL 和相关工具 sudo apt install -y postgresql postgresql-contrib # 2. 修改 PostgreSQL 配置以允许远程连接 # 编辑 postgresql.conf 文件,将 listen_addresses 从 'localhost' 改为 '*' # 注意:您的 PostgreSQL 版本可能不同,请相应调整路径(例如 /etc/postgresql/16/main/) # 您可以通过 `pg_lsclusters` 查看版本和路径 sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" /etc/postgresql/$(pg_lsclusters | awk 'NR==2 {print $1}')/main/postgresql.conf # 3. 修改 pg_hba.conf 文件以允许来自任何 IP 地址的 md5 密码认证连接 # 同样,注意 PostgreSQL 版本路径 echo "host all all 0.0.0.0/0 md5" | sudo tee -a /etc/postgresql/$(pg_lsclusters | awk 'NR==2 {print $1}')/main/pg_hba.conf # 4. 重启 PostgreSQL 服务使配置生效 sudo systemctl restart postgresql # 5. 设置 PostgreSQL 的 postgres 用户密码(重要!) # 将 'YourSecurePostgresPassword!' 替换为您自己的强密码 sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'YourSecurePostgresPassword!';" 可视化操作与安全组说明 (PostgreSQL) 云服务器安全组: 在您的云服务提供商(如阿里云、腾讯云、AWS)的控制台中,找到您的服务器实例对应的安全组(或防火墙规则)。 添加入站规则,允许来自您需要访问数据库的 IP 地址(或者为了开发方便暂时允许 0.0.0.0/0,但生产环境不推荐)访问 PostgreSQL 的默认端口 5432/TCP。 数据库客户端连接: 您可以使用图形化数据库管理工具(如 pgAdmin, DBeaver, Navicat 等)从您的本地计算机连接到服务器上的 PostgreSQL。 连接信息: 主机/服务器地址: YOUR_SERVER_IP (例如 123.45.6.78) 端口: 5432 数据库: 默认可以是 postgres 用户名: postgres 密码: 您在上面第 5 步设置的 YourSecurePostgresPassword! 创建专用数据库和用户 (推荐): 虽然您可以使用 postgres 超级用户,但更安全的做法是为您的 Django 应用创建一个专用的数据库和用户。登录后,在 SQL 工具中执行: CREATE DATABASE myproject_db; CREATE USER myproject_user WITH PASSWORD 'MyProjectSecurePassword!'; GRANT ALL PRIVILEGES ON DATABASE myproject_db TO myproject_user; ALTER ROLE myproject_user CREATEDB; -- 可选,如果需要用户创建数据库 之后在 Django 的 settings.py 中使用这些新的凭据。 第 4 步:部署 MinIO 对象存储 (使用 Docker) MinIO 将用于存储 Django 应用的媒体文件和静态文件。 wget https://dl.min.io/client/mc/release/linux-amd64/mc chmod +x mc sudo mv mc /usr/local/bin/ # 1. 创建 MinIO 数据存储目录 sudo mkdir -p /minio/data sudo chmod -R 777 /minio/data # 临时给予宽松权限,生产环境应更精细控制 # 2. 使用 Docker 启动 MinIO 容器 # 将 'YourMinioAdminUser' 和 'YourMinioAdminPassword!' 替换为您自己的凭据 # 确保密码足够复杂(至少8位,包含大小写、数字、特殊字符) docker run -d \ --name minio \ -p 9000:9000 \ -p 9001:9001 \ -v /minio/data:/data \ -e "MINIO_ROOT_USER=admin" \ -e "MINIO_ROOT_PASSWORD=YourSecureMinioPassword!" \ quay.io/minio/minio:latest \ server /data --console-address ":9001" # 2. 设置别名(注意用单引号包裹密码) mc alias set myminio http://123.45.6.78:9000 admin 'YourSecureMinioPassword!' # 2. 修改密码 mc admin user password myminio admin 'NewSecurePass123!' 可视化操作与安全组说明 (MinIO) 云服务器安全组: 开放 MinIO API 端口: 9000/TCP 开放 MinIO 控制台端口: 9001/TCP 访问 MinIO 控制台: 在浏览器中打开 http://YOUR_SERVER_IP:9001 (例如 http://123.45.6.78:9001)。 使用您在 docker run 命令中设置的 MINIO_ROOT_USER (例如 admin) 和 MINIO_ROOT_PASSWORD (例如 YourSecureMinioPassword!) 登录。 创建存储桶 (Buckets): 登录 MinIO 控制台后,点击 “Buckets” -> “Create Bucket”。 创建两个存储桶: media (用于存储用户上传的文件) static (用于存储 Django 的静态文件) 重要: 为这两个存储桶设置访问策略 (Access Policy)。对于公开访问的静态文件和媒体文件,您可能需要将策略设置为 public 或 readonly (根据需求)。点击存储桶旁边的 “Manage” -> “Access Policy”,选择 “Add Policy”,然后选择 readonly 或 download (对于 public,可以直接在创建时设置)。更精细的权限控制请参考 MinIO 文档。 第 5 步:部署 Django 后端应用 (使用 Docker) 5.1 准备 Django 项目代码 # 1. 克隆您的 Django 项目代码 (替换为您的仓库地址) # git clone https://github.com/your-username/your-backend-repo.git # cd your-backend-repo # 假设您已将代码上传到服务器的某个目录,例如 /srv/django-app # cd /srv/django-app # 2. 配置 Django settings.py (或通过环境变量传递) # 确保您的 settings.py 文件中数据库和 MinIO 配置正确。 # 数据库示例 (使用您在 PostgreSQL 步骤中创建的用户和数据库): # DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.postgresql', # 'NAME': 'myproject_db', # 'USER': 'myproject_user', # 'PASSWORD': 'MyProjectSecurePassword!', # 'HOST': 'YOUR_SERVER_IP', # Django 容器需要能访问到宿主机的 PostgreSQL # 'PORT': '5432', # } # } # # MinIO (django-storages) 示例: # DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' # STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' # AWS_ACCESS_KEY_ID = 'admin' # MinIO Root User # AWS_SECRET_ACCESS_KEY = 'YourSecureMinioPassword!' # MinIO Root Password # AWS_STORAGE_BUCKET_NAME = 'media' # 默认文件存储桶 # AWS_S3_ENDPOINT_URL = 'http://YOUR_SERVER_IP:9000' # MinIO API 地址 # AWS_S3_OBJECT_PARAMETERS = { 'CacheControl': 'max-age=86400', } # AWS_DEFAULT_ACL = None # 或 'public-read' 根据需求 # AWS_S3_USE_SSL = False # 如果 MinIO 没有配置 SSL # AWS_S3_VERIFY = True # 如果 MinIO 使用自签名证书,可能需要设为 False 或提供证书路径 # AWS_S3_REGION_NAME = 'us-east-1' # MinIO 不需要区域,但 boto3 可能需要 # AWS_S3_SIGNATURE_VERSION = 's3v4' # STATIC_URL = f'{AWS_S3_ENDPOINT_URL}/static/' # 如果使用 MinIO 存储静态文件 # MEDIA_URL = f'{AWS_S3_ENDPOINT_URL}/media/' # # **重要**: 确保 Django 容器可以访问到 PostgreSQL 和 MinIO。 # 如果 PostgreSQL 和 MinIO 也在 Docker 中运行,并且在同一个 Docker 网络中, # 可以使用容器名作为 HOST (例如 'minio' 而不是 'YOUR_SERVER_IP')。 # 如果 PostgreSQL 在宿主机上运行,Django 容器可以使用宿主机的 IP 或 `host.docker.internal` (某些 Docker 版本)。 5.2 创建 Dockerfile 在您的 Django 项目根目录下创建一个名为 Dockerfile 的文件: # Dockerfile FROM python:3.10-slim # 设置工作目录 WORKDIR /app # 设置 pip 国内镜像源 (可选, 加快构建速度) RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple # 复制依赖文件并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制项目代码到工作目录 COPY . . # 暴露 Django 应用运行的端口 EXPOSE 8000 # 运行 Django 开发服务器 (生产环境推荐使用 Gunicorn 或 uWSGI) # CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] # 使用 Gunicorn (确保 gunicorn 在 requirements.txt 中) CMD ["gunicorn", "your_project_name.wsgi:application", "--bind", "0.0.0.0:8000"] # 将 your_project_name 替换为您的 Django 项目的实际名称 (wsgi.py 所在的目录名) 5.3 构建并运行 Django Docker 镜像 在包含 Dockerfile 的 Django 项目根目录下执行: # 构建 Docker 镜像 (将 django-backend 替换为您的镜像名) docker build -t django-backend . # 运行 Django 容器 # 确保旧的同名容器已停止并移除: # docker stop django-app && docker rm django-app docker run -d \ -p 8000:8000 \ -e DJANGO_SETTINGS_MODULE=your_project_name.settings \ --name django-app \ django-backend # 将 your_project_name.settings 替换为您的 Django settings 文件路径 第 6 步:配置 Nginx 反向代理 Nginx 将作为前端服务器,接收外部请求并将其转发到 Django 应用。 # 1. 创建 Nginx 配置文件 # 将 YOUR_SERVER_IP 替换为您的服务器公网 IP 或域名 sudo bash -c "cat <<EOF > /etc/nginx/sites-available/django_proxy server { listen 80; server_name YOUR_SERVER_IP; # 例如 123.45.6.78 或 example.com location / { proxy_pass http://127.0.0.1:8000; # Django 应用运行的地址和端口 proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; } location /static/ { # 如果 Django 自己处理静态文件 (DEBUG=True) alias /srv/django-app/staticfiles/; # 替换为你的 Django 项目静态文件收集目录 } location /media/ { # 如果 Django 自己处理媒体文件 (DEBUG=True) alias /srv/django-app/media/; # 替换为你的 Django 项目媒体文件目录 } } EOF" # 2. 创建符号链接以启用该配置 # 先删除可能存在的默认配置的符号链接(如果它占用了 default_server) # sudo rm /etc/nginx/sites-enabled/default sudo ln -s /etc/nginx/sites-available/django_proxy /etc/nginx/sites-enabled/django_proxy # 3. 测试 Nginx 配置 sudo nginx -t # 4. 重启 Nginx 服务 sudo systemctl restart nginx 可视化操作与安全组说明 (Nginx & Django) 云服务器安全组: 确保 HTTP 端口 80/TCP 已对公网开放。 如果未来配置 HTTPS,也需要开放 443/TCP。 访问您的应用: 在浏览器中输入 http://YOUR_SERVER_IP (例如 http://123.45.6.78)。 如果一切配置正确,您应该能看到您的 Django 应用首页。 如果部署了 Swagger,可以尝试访问 http://YOUR_SERVER_IP:8000/api/swagger/ (路径取决于您的 Django URL 配置)。 第 7 步:自动化部署脚本 将以下脚本保存为 deploy_django_stack.sh,赋予执行权限 (chmod +x deploy_django_stack.sh),然后运行它。 请务必在使用前仔细阅读脚本内容,并根据您的实际情况修改占位符和配置! #!/bin/bash # --- 配置变量 (请务必根据您的实际情况修改!) --- SERVER_IP="123.45.6.78" # 您的服务器公网 IP POSTGRES_PASSWORD="YourSecurePostgresPassword!" MINIO_ROOT_USER="admin" MINIO_ROOT_PASSWORD="YourSecureMinioPassword!" DJANGO_PROJECT_NAME="backend" # 您 Django 项目中包含 wsgi.py 的目录名 # DJANGO_REPO_URL="https://github.com/your-username/your-backend-repo.git" # 您的 Django 代码仓库地址 # DJANGO_PROJECT_DIR="/srv/django-app" # Django 项目将被克隆/放置到的目录 echo "--- 服务器部署脚本 ---" echo "服务器 IP 将被设置为: $SERVER_IP" echo "PostgreSQL 'postgres' 用户密码将设置为: $POSTGRES_PASSWORD" echo "MinIO 管理员用户: $MINIO_ROOT_USER" echo "MinIO 管理员密码: $MINIO_ROOT_PASSWORD" echo "Django 项目名 (用于 Gunicorn): $DJANGO_PROJECT_NAME" # echo "Django 代码仓库: $DJANGO_REPO_URL" # echo "Django 项目目录: $DJANGO_PROJECT_DIR" read -p "确认以上信息正确并开始部署吗?(yes/no): " confirmation if [ "$confirmation" != "yes" ]; then echo "部署已取消。" exit 1 fi echo "--- 1. 系统初始化与依赖安装 ---" sudo apt update && sudo apt upgrade -y sudo apt install -y ca-certificates curl gnupg lsb-release nginx git echo "--- 2. 安装 Docker CE 和 Docker Compose ---" sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<EOF { "registry-mirrors": [ "https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com", "https://registry.docker-cn.com" ] } EOF sudo systemctl daemon-reload sudo systemctl restart docker sudo usermod -aG docker $USER echo "Docker 安装完成。请重新登录或执行 'newgrp docker' 以应用 docker 组权限。" echo "按 Enter 继续..." read echo "--- 3. 安装 PostgreSQL 并配置 ---" sudo apt install -y postgresql postgresql-contrib PG_VERSION=$(pg_lsclusters | awk 'NR==2 {print $1}') if [ -z "$PG_VERSION" ]; then echo "错误:无法检测到 PostgreSQL 版本。请手动配置。" exit 1 fi echo "检测到 PostgreSQL 版本: $PG_VERSION" sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" /etc/postgresql/$PG_VERSION/main/postgresql.conf sudo sh -c "echo 'host all all 0.0.0.0/0 md5' >> /etc/postgresql/$PG_VERSION/main/pg_hba.conf" sudo systemctl restart postgresql sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '$POSTGRES_PASSWORD';" echo "PostgreSQL 安装和配置完成。" echo "--- 4. 部署 MinIO 对象存储 ---" sudo mkdir -p /minio/data sudo chmod -R 777 /minio/data # 确保 Docker 有权限写入 docker stop minio || true && docker rm minio || true # 确保旧容器被移除 docker run -d \ --name minio \ -p 9000:9000 \ -p 9001:9001 \ -v /minio/data:/data \ -e "MINIO_ROOT_USER=${MINIO_ROOT_USER}" \ -e "MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}" \ quay.io/minio/minio:latest \ server /data --console-address ":9001" echo "MinIO 部署完成。请访问 http://$SERVER_IP:9001 并使用以下凭据登录:" echo "用户名: $MINIO_ROOT_USER" echo "密码: $MINIO_ROOT_PASSWORD" echo "登录后,请手动创建 'media' 和 'static' 存储桶,并根据需要设置其访问策略为公开可读。" echo "按 Enter 继续..." read echo "--- 5. 部署 Django 后端应用 ---" # echo "克隆 Django 项目代码从 $DJANGO_REPO_URL 到 $DJANGO_PROJECT_DIR..." # sudo mkdir -p $DJANGO_PROJECT_DIR # sudo chown $USER:$USER $DJANGO_PROJECT_DIR # 确保当前用户有权限 # git clone $DJANGO_REPO_URL $DJANGO_PROJECT_DIR # cd $DJANGO_PROJECT_DIR echo "假设 Django 项目代码已位于当前目录或指定目录。" echo "请确保您的 Django 项目 (例如: ./backend/settings.py) 已配置好数据库和 MinIO 连接。" echo "数据库主机应指向 '$SERVER_IP' (如果 PostgreSQL 在宿主机上运行)。" echo "MinIO Endpoint URL 应指向 'http://$SERVER_IP:9000'。" echo "按 Enter 继续以创建 Dockerfile 并构建镜像..." read # 创建 Dockerfile cat <<EOF > Dockerfile FROM python:3.10-slim ENV PYTHONUNBUFFERED 1 WORKDIR /app RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8000 # 将 your_project_name 替换为您的 Django 项目名 (wsgi.py 所在的目录名) CMD ["gunicorn", "${DJANGO_PROJECT_NAME}.wsgi:application", "--bind", "0.0.0.0:8000"] EOF echo "Dockerfile 已创建。" echo "构建 Django Docker 镜像 (django-backend)..." docker build -t django-backend . echo "运行 Django Docker 容器 (django-app)..." docker stop django-app || true && docker rm django-app || true # 确保旧容器被移除 docker run -d \ -p 8000:8000 \ -e DJANGO_SETTINGS_MODULE=${DJANGO_PROJECT_NAME}.settings \ --name django-app \ django-backend echo "Django 应用容器已启动。" echo "按 Enter 继续配置 Nginx..." read echo "--- 6. 配置 Nginx 反向代理 ---" # Nginx 已在步骤1安装 sudo bash -c "cat <<EOF > /etc/nginx/sites-available/django_proxy server { listen 80; server_name $SERVER_IP; client_max_body_size 100M; # 允许上传大文件 location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; } # 如果您希望 Nginx 直接处理静态文件和媒体文件 (生产环境推荐) # 请确保 Django 的 collectstatic 已将文件收集到 Nginx 可访问的路径 # location /static/ { # alias /path/to/your/django_project/staticfiles/; # 替换为实际路径 # } # location /media/ { # alias /path/to/your/django_project/mediafiles/; # 替换为实际路径 # } } EOF" # 确保旧的 default 站点(如果存在且冲突)被禁用 if [ -L /etc/nginx/sites-enabled/default ]; then sudo rm /etc/nginx/sites-enabled/default fi # 强制创建或更新符号链接 sudo ln -sf /etc/nginx/sites-available/django_proxy /etc/nginx/sites-enabled/django_proxy echo "测试 Nginx 配置..." sudo nginx -t if [ \$? -ne 0 ]; then echo "Nginx 配置测试失败!请检查 /etc/nginx/sites-available/django_proxy 文件。" exit 1 fi echo "重启 Nginx 服务..." sudo systemctl restart nginx echo "Nginx 配置完成。" echo "--- 部署完成!---" echo "请确保您的云服务器安全组已开放以下端口:" echo " - PostgreSQL: 5432/TCP (如果需要远程访问数据库)" echo " - MinIO API: 9000/TCP" echo " - MinIO 控制台: 9001/TCP" echo " - HTTP (Nginx): 80/TCP" echo "" echo "您现在应该可以通过 http://$SERVER_IP 访问您的 Django 应用。" echo "MinIO 控制台: http://$SERVER_IP:9001" echo "如果 Django 应用需要数据库迁移,请在容器内执行:" echo " docker exec -it django-app python manage.py makemigrations your_app_name" echo " docker exec -it django-app python manage.py migrate" echo "如果需要创建超级用户:" echo " docker exec -it django-app python manage.py createsuperuser" 8. 用户数据迁移策略 (可选) 当系统用户量增长,或者需要从旧系统迁移数据时,需要考虑数据迁移策略。 新用户注册与数据处理: Django Auth: Django 自带的 django.contrib.auth 系统能很好地处理新用户注册、密码哈希存储、登录认证等。当新用户通过您的 API (例如 /api/register/) 注册时,会在 auth_user 表(或您自定义的用户模型表)中创建一条记录。 关联用户信息 (UserInfo): 如果您有一个单独的 UserInfo 模型通过 OneToOneField 或 ForeignKey 关联到主用户模型,确保在用户注册成功后,或用户首次编辑个人资料时,创建或更新对应的 UserInfo 记录。user_id 将作为关联两个表的键。 从旧系统迁移数据 (如果适用): 数据导出: 从旧系统导出用户数据,通常为 CSV、JSON 或 SQL dump 格式。 数据清洗与转换: 清洗数据,使其符合新系统的数据模型。特别注意密码的处理,如果旧系统密码哈希算法与 Django 不兼容,用户可能需要在首次登录新系统时重置密码。 数据导入: Django 管理命令: 编写自定义的 Django management command (python manage.py your_custom_command),使用 Django ORM 来创建用户和关联信息。这是推荐的方式,因为它会处理所有模型逻辑和信号。 直接 SQL: 对于非常大的数据集,直接使用 SQL 导入到 PostgreSQL 可能更快,但需要非常小心,确保数据完整性和关联正确,并且后续可能需要手动处理 Django 的 contenttypes 等。 第三方库: 例如 django-import-export 库可以帮助处理复杂的数据导入导出。 数据完整性与验证: 在导入过程中,使用 Django 模型的 full_clean() 方法或表单验证来确保数据符合新模型的约束。 利用数据库的约束(如 UNIQUE, NOT NULL)来保证数据质量。 处理静态文件和媒体文件 (如头像): 如果旧系统有用户上传的文件,需要将这些文件迁移到新的存储位置(例如 MinIO)。 更新数据库中指向这些文件的路径或 URL。 如果文件名或路径结构发生变化,需要编写脚本来批量更新。 扩展性考虑: 数据库: PostgreSQL 本身具有良好的扩展性。对于非常大的负载,可以考虑读写分离、分区等策略。 Django 应用: 使用 Gunicorn 或 uWSGI 配合多个 worker 进程可以处理更多并发请求。Nginx 作为反向代理可以进行负载均衡。 缓存: 对常用数据和计算结果使用缓存(如 Redis、Memcached)可以显著提高性能。 备份与恢复: 数据库: 定期使用 pg_dump 备份 PostgreSQL 数据库。制定恢复计划。 MinIO: 定期备份 MinIO 的数据卷 (/minio/data)。MinIO 也支持自身的复制和纠删码功能来提高数据可靠性。 应用代码和配置: 使用版本控制 (如 Git) 管理代码,并备份 Docker 镜像和相关配置文件。 9. MinIO 和 Django (Docker) Debug 指南 在部署和运行 MinIO 及 Docker化的 Django 应用时,可能会遇到一些常见问题。以下是一些调试步骤和技巧,结合了您之前遇到的情况: 9.1 MinIO Client (mc) 相关问题 mc: Segmentation fault: 原因: mc 二进制文件损坏、与系统架构不兼容(例如在 ARM 服务器上运行了 AMD64 版本)或下载不完整。 解决方案: 彻底卸载旧/损坏的 mc: sudo rm -f /usr/local/bin/mc which mc # 确认已删除,应无输出 下载正确的官方版本 (假设为 linux-amd64): wget https://dl.min.io/client/mc/release/linux-amd64/mc chmod +x mc sudo mv mc /usr/local/bin/ 验证: mc --version 检查文件类型: file /usr/local/bin/mc (应显示 ELF 64-bit LSB executable, x86-64,...) mc alias set ...: The request signature we calculated does not match…: 原因: Access Key / Secret Key 错误: 您提供的 admin 和 SecurePassword123! (或您实际使用的密码) 与 MinIO 服务启动时配置的 MINIO_ROOT_USER / MINIO_ROOT_PASSWORD 不匹配。 Endpoint URL 错误: URL 格式不正确 (例如多了斜杠 http://123.45.6.78/:9000) 或地址/端口错误。正确应为 http://YOUR_SERVER_IP:9000。 MinIO 服务未运行或端口 9000 未正确映射/防火墙未开放。 解决方案: 确认 MinIO 容器正在运行且端口 9000 已映射: docker ps | grep minio 仔细核对 mc alias set 命令中的 Access Key (用户名), Secret Key (密码), 和 Endpoint URL。 确保密码中没有特殊字符导致命令行解析问题,或者用单引号包裹密码:mc alias set myminio http://123.45.6.78:9000 admin 'YourSecureMinioPassword!' mc admin user password ...: password is not a recognized command: 原因: mc 版本过旧,不支持该子命令。 命令语法错误。 解决方案: 升级 mc: 确保您使用的是最新版本的 mc (参考上面安装步骤)。 正确语法: mc admin user password ALIAS USERNAME NEW_PASSWORD 例如: mc admin user password myminio admin 'NewSecurePassword123!' (确保 myminio 别名已成功设置)。 9.2 Docker 相关问题 docker run ...: address already in use (e.g., for port 8000): 原因: 您尝试映射到宿主机的端口 (例如 8000) 已经被其他进程占用。 解决方案: 查找并停止占用端口的进程: sudo lsof -i :8000 # 或 sudo netstat -tulnp | grep 8000 # 找到 PID 后,使用 sudo kill <PID> 或 sudo kill -9 <PID> 如果占用者是另一个 Docker 容器,先停止并移除它: docker ps -a # 查看所有容器,找到占用端口的容器 docker stop <container_id_or_name> docker rm <container_id_or_name> 或者,更改您当前要运行的容器的端口映射,例如将 Django 映射到宿主机的 8001 端口: docker run -p 8001:8000 ... (同时需要更新 Nginx 配置中的 proxy_pass 指向 http://127.0.0.1:8001;) docker run ...: Conflict. The container name “/django-app” is already in use…: 原因: 已存在一个同名的 Docker 容器 (即使它已停止)。 解决方案: 删除旧的同名容器: docker rm django-app (如果容器已停止) 或 docker stop django-app && docker rm django-app (如果正在运行)。 或者,为新容器指定一个不同的名称:docker run --name django-app-v2 ... docker run ...: invalid reference format或django-backend: command not found`: 原因: Docker 无法找到您指定的镜像 django-backend。 镜像名称拼写错误或大小写不匹配 (Docker 镜像名通常是小写)。 镜像尚未成功构建,或者构建时使用了不同的标签。 解决方案: 确认镜像是否存在且名称正确: docker images | grep django-backend 如果不存在,请确保在 Django 项目根目录 (包含 Dockerfile) 下重新构建: docker build -t django-backend . 确保 docker run 命令中使用的镜像名称与 docker images 中显示的完全一致。 9.3 Django (Docker 内部) 调试 检查 Django 容器状态和日志: docker ps -a | grep django-app # 查看容器是否正在运行 docker logs django-app # 查看 Django 容器的实时日志(非常重要!) 日志会显示 Gunicorn/Django 的启动信息、任何 Python 错误、数据库连接问题等。 进入 Django 容器内部进行调试: docker exec -it django-app bash # 进入容器的 shell 进入容器后,您可以: 检查文件是否存在,路径是否正确。 手动运行 python manage.py check 查看是否有配置问题。 尝试连接数据库:python manage.py dbshell (如果安装了 psql 客户端)。 查看环境变量是否正确设置。 数据库连接问题: 错误: 日志中可能出现 OperationalError: could not connect to server 或类似错误。 检查: PostgreSQL 服务是否在宿主机或另一容器中运行。 Django settings.py 中的 DATABASES 配置(HOST, PORT, NAME, USER, PASSWORD)是否正确。 如果 PostgreSQL 在宿主机,Django 容器是否能访问到宿主机的 IP 和端口。可能需要在 docker run 时使用 --network="host" (不推荐,除非必要) 或确保 Docker 网络配置允许。更常见的是使用服务器的公网 IP (确保 PostgreSQL 监听 * 且防火墙允许)。 PostgreSQL 的 pg_hba.conf 是否允许来自 Docker 容器 IP 地址范围的连接。 9.4 Nginx 调试 nginx: [emerg] invalid number of arguments in "proxy_set_header" directive...: 原因: proxy_set_header 指令语法错误,通常是参数数量不对或变量名错误。 示例错误: proxy_set_header X-Forwarded-For $remote_addr; 正确示例: proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 解决方案: 仔细检查 Nginx 配置文件 (/etc/nginx/sites-available/django_proxy) 中的所有 proxy_set_header 指令,确保它们都遵循 proxy_set_header <字段名> <值>; 的格式。 注意变量: Nginx 内置变量如 $host, $remote_addr, $proxy_add_x_forwarded_for 不需要额外的转义符。 Nginx 502 Bad Gateway: 原因: Nginx 无法连接到 proxy_pass 指令中指定的后端 Django 应用。 解决方案: 确认 Django 容器运行: docker ps | grep django-app。 检查 Django 容器日志: docker logs django-app,查看是否有启动错误。 确认 Django 监听端口: 确保 Django 应用 (Gunicorn) 在容器内部监听 0.0.0.0:8000。 确认 Nginx proxy_pass 地址: 通常是 http://127.0.0.1:8000; (因为 Django 容器的 8000 端口映射到了宿主机的 8000 端口,Nginx 从宿主机访问此端口)。 网络测试: 在服务器上尝试 curl http://127.0.0.1:8000,看是否能访问到 Django 应用。 Django 404 for /swagger/ (但 /api/swagger/ works): 原因: 访问的 URL 路径与 Django urls.py 中定义的路由不匹配。 解决方案: 确保您在浏览器中访问的是 Django urls.py 中为 Swagger UI 定义的正确路径,例如 http://YOUR_SERVER_IP/api/swagger/。 9.5 通用调试技巧 逐步验证: 从底层服务(PostgreSQL, MinIO)开始,确保它们独立运行时正常,然后再验证 Django 应用,最后是 Nginx。 简化配置: 如果遇到复杂问题,尝试暂时简化配置(例如,移除 Nginx,直接暴露 Django 容器端口进行测试)以缩小问题范围。 查看所有日志: 同时关注 PostgreSQL, MinIO, Django (Gunicorn), Nginx 的日志,它们通常会提供关键的错误信息。 网络工具: 使用 ping, curl, telnet, netstat, ss 等工具检查网络连通性和端口监听情况。 # 检查端口是否被监听 sudo netstat -tulnp | grep 5432 # PostgreSQL sudo netstat -tulnp | grep 9000 # MinIO API sudo netstat -tulnp | grep 9001 # MinIO Console sudo netstat -tulnp | grep 8000 # Django App / Nginx sudo netstat -tulnp | grep 80 # Nginx 通过这些步骤,您应该能够定位并解决部署过程中遇到的大部分问题。
Techniques
· 2025-10-07
<
>
Touch background to close