惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
V
V2EX
Jina AI
Jina AI
S
Schneier on Security
Cyberwarzone
Cyberwarzone
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
PCI Perspectives
PCI Perspectives
美团技术团队
小众软件
小众软件
L
LangChain Blog
N
Netflix TechBlog - Medium
大猫的无限游戏
大猫的无限游戏
T
Threatpost
T
Tor Project blog
K
Kaspersky official blog
Microsoft Security Blog
Microsoft Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
Security Latest
Security Latest
H
Heimdal Security Blog
N
News and Events Feed by Topic
T
Threat Research - Cisco Blogs
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
M
MIT News - Artificial intelligence
Apple Machine Learning Research
Apple Machine Learning Research
N
News | PayPal Newsroom
I
Intezer
博客园 - 聂微东
U
Unit 42
Cisco Talos Blog
Cisco Talos Blog
量子位
T
The Exploit Database - CXSecurity.com
Last Week in AI
Last Week in AI
博客园_首页
月光博客
月光博客
Webroot Blog
Webroot Blog
I
InfoQ
The Cloudflare Blog
Attack and Defense Labs
Attack and Defense Labs
人人都是产品经理
人人都是产品经理
Project Zero
Project Zero
Hacker News: Ask HN
Hacker News: Ask HN
IT之家
IT之家
Google DeepMind News
Google DeepMind News
C
Cisco Blogs

BlogFinder

日常漫步 Vol.24 之漫步前山河 - 雅余 周报 #1-聊聊本周的收获 - Edwin's Blog 我的OpenCode必装插件与Skill Write Something 掌中之物未必在掌握之中 · CRIVU PiliNara,一个更顺手的 PiliPlus 分支 「NekoEcho」:做一个必有回响的猫娘主题博客 2026-05 书影音总结 简化博客主题 - 安迪 我第一次发布 npm 包 拾花小记#45:中考前的二三事 – 小改学习志 黛西花园5月游 #18 枇杷又熟了的五月月报 一些奇奇怪怪的需求?word仿方正书版的几个小操作 - Xiobb's Blog 0419 御温泉之旅 修复了一些bug,网站基本上趋于稳定了 - 新锐博客 又回到四十年前 如何定义成功 迷鹿屋2026已重新上线 科技冰火两重天+一周回顾 ${title} 热度退了,我反而用得更深了-咕咚同学 我到底该不该换个域名? 随身WIFI折腾记 - 安迪 博客撰写体验提升——hexo pro插件 为什么不用相机把屏幕上的接关密码拍下来? 国清寺与天台山 – Ouroboros ★★★★☆《挽救计划》——久违的经济上行感 - Davidの3号基地 删除右键“打开方式”里多余选项 第三周刊_No.53|一切都会被支付两次 安卓APP通话记录与录音上传踩坑记录 - 子舒的博客 天量下跌 inBox 笔记 2.3.8,把工具栏交给了你-咕咚同学 我把小龙虾搬到了微信-咕咚同学 安好 - 响石潭 Compound Engineering Plugin:让每个工程单元都比上一个更容易 MOSS-TTS Family:开源高质量语音与声音生成模型家族深度解析 Crawl4AI:专为 LLM 设计的开源 Web 爬虫与数据抓取工具 Build Your Own X:从零实现你最喜欢的技术——程序员进阶的终极资源清单 Anthropic Skills:用文件夹教 Claude 专业技能的开源框架 1年的去月球(下) - 梅之夏 欢迎回来。 简单讲讲 ASN.1 与 OID DTV - 直播聚合客户端 5.22-5.27 – 不兴江 还没去过鸭川 – 不兴江 张晶晶同学三刷林志颖 关于我 – 不兴江 爱与嫉妒 – 不兴江 港股被持续做空 备案码花了四百块-咕咚同学 一句话生成封面:我给公众号做了4种风格的AI封面生成技能 「官」方認證 再谈费曼学习法 2026-05-28T00:34:11+08:00 2026-05-28T00:28:45+08:00 离谱的英语学习指南:基于AI的英语进阶系统方法论 iii:零集成架构的后端统一运行时 Claude Code Harness:让 Claude Code 工作有迹可循的工程化框架 Heretic:全自动移除大语言模型审查机制的开源工具 MarkItDown:微软开源的万能文档转 Markdown 利器 Harness:让 Claude Code 秒变多智能体协作工厂 这段时间尽折腾AI Agent了,确实极大地提高了效率 近期动态:两个新站点正式上线啦 误判解除!zhouayuan.com 腾讯安全申诉成功 - 周阿源|玩具设计・插画日常・生活随笔 Ralph:让 AI 编码工具自主循环跑完所有 PRD 任务的量产神器 全都违法 – 个人工作记录 关于zhouayuan.com被误判 “含违规信息” 的说明与申诉记录 - 周阿源|玩具设计・插画日常・生活随笔 小米 MiMo v2.5 Pro 白嫖 最大的人间清醒,兜里有钱,但是不花。 夜晚靓歌(12):于文文现场solo - 王志勇的Blog 今日插画:风扬起的倔强 - 周阿源|玩具设计・插画日常・生活随笔 回门习俗 独立网卡 - 忘记了回忆 500亿入股人工智能企业 从命令行到桌面智能体-咕咚同学 第一性原理读书笔记 行者微评论223-加班の守株待兔-博客|政治与时事-风雨行者 ZOZO开源物理接触求解器:GPU加速的可扩展仿真引擎 OpenStock:开源股票市场交易平台技术深度解析 MoneyPrinterTurbo:基于AI的全自动短视频生成工具深度解析 Claude-Mem:为 Claude Code 构建的持久化记忆压缩系统 Twenty:可代码化定制的企业级开源 CRM 平台技术深度解析 2026-05-26T22:59:17+08:00 企业级开源大模型部署平台 GPUStack 实战教程 1年的去月球(上) - 梅之夏 Sevalla - 静态网站托管服务 不用翻墙、不用注册、不用月费,普通人也能用上 Claude Code 装修灯具要注意⚠️ 黄梅天先锋 - 游子微博 公安备案顺利办结,站点备案全部完成 - 周阿源|玩具设计・插画日常・生活随笔 第三次兑换天猫超市卡了宗宗酱-三维狐少儿编程 Don't think, feel. - Rolen's Blog 人这一辈子,到底图个什么 博客迁移 - Edwin's Blog 情感赛道写作模板 再现本轮行情的典型特征 裁员与平常心-咕咚同学 别让“偷懒”,成为隐私泄露的破绽 片刻 - Jdeal | Life is like a Design.
人工智能实训Day1:Ubuntu 基础与 Conda 推理环境搭建 | 姓王者的博客
作者:xingwangzhe · 2026-06-22 · via BlogFinder

前言

不出意外的,我的实训 II 被调剂到人工智能方向了,我感觉这个还挺有意思的,先记录一下。

人工智能预训练

分配 Ubuntu 用户

老师说为了实训,好不容易申请到 H200 来用,不过分配到 70 多个人、10 多个小组,都是 Docker 分块。

____ _ _ _ ___

/ ___|(_) |_ ___ _ __ / \ |_ _|

\___ \| |__/ _ \| '_ \ / _ \ | |

___) | | || (_) | | | |/ ___ \ | |

|____/|_|\__\___/|_| |_/_/ \_\___|

操作系统: Ubuntu 22.04.5 LTS, x86_64

处 理 器: INTEL(R) XEON(R) GOLD 6530, 5 核心

内 存: 41.0 GB

运 算 卡: NVIDIA H200 NVL, 1, 23552 MiB

存 储:

挂载点 操作权限 分区使用率 已使用/总空间

/ 读写 9% 22G/258G

/root/siton-pub 只读 13% 98G/816G

/root/siton-data-1f55405a64d24fe2819a81c90df30517 读写 52% 67G/128G

/root/siton-tmp 读写 1% 12K/256G

*温馨提示:

1.系统盘空间较小,请将较大的数据存放在网盘或者缓存盘中。

2.重置系统时缓存盘与网盘中的数据不受影响。

3.帮助文档: https://docs.aiserver.cn/SitonCloud/introduction/。

4.使用过程中如有疑问,请咨询系统管理员或联系思腾合力技术支持

Last login: Mon Jun 22 11:18:26 2026 from 127.0.0.1

-bash: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8)

服务器不连网?

指导书上写的是用 VS Code 的 Remote-SSH 连接,而且只在大内网里才能连上,也就是服务器不能联网下载 VS Code Server,得客户端下载之后再 copy 到服务器里,才能做好完整的 VS Code Server 连接。

{

"remote.SSH.localServerDownload": "always",

"remote.SSH.remotePlatform": {

"ubuntu-offline": "linux",

"ubuntu-lihengyu": "linux"

},

"remote.SSH.showLoginTerminal": true

}

“remote.SSH.localServerDownload”: “always”

这项设置会让 VS Code Server 先由本机下载,再上传到离线 Ubuntu 服务器,从而避免服务器无法联网下载组件的问题。设置完成后,可以在 Remote-SSH: Connect to Host 中选择已经配置好的主机名进行连接。

但我 apt install 的时候看见了阿里云镜像,恩……也不是没联网嘛。

逐个任务

Problem (linux1): Understanding Linux and Ubuntu

(a) Linux 和 Ubuntu 是同一个东西吗?

不是 Linux 是操作系统的内核,而 Ubuntu 是基于 Linux 内核构建的一个发行版。可以把 Linux 理解为汽车发动机,Ubuntu 则是搭载这个发动机的一款整车。

(b) 为什么人工智能实训课程常使用 Ubuntu,而不是只使用 Windows?

  1. 深度学习环境配置:主流 AI 框架(PyTorch、TensorFlow 等)和 CUDA 驱动在 Linux/Ubuntu 上的支持更成熟,安装和版本管理更方便。
  2. 服务器使用:实际训练和推理通常跑在远程服务器上,Ubuntu Server 稳定、占用资源少,适合长时间运行的 GPU 任务。
  3. 命令行操作:Ubuntu 拥有强大的 Shell 和包管理工具(apt、Conda、pip),便于自动化脚本、环境复现和批量任务。

Problem (vscode1): Connecting to the Ubuntu server

课程要求使用 VS Code + Remote-SSH 连接服务器,但我电脑上 VS Code 有些问题,所以改用 Zed 的远程开发功能连接,本质一样:都是在本地编辑器里操作远程 Ubuntu 服务器的文件和终端。

完成步骤:

  1. 在本地安装 Zed(或 VS Code)。
  2. 配置 SSH 连接到课程提供的 Ubuntu 服务器(202.199.13.141)。
  3. 在远程终端中依次运行以下命令:

whoami

hostname

pwd

uname -a

运行结果截图如下:

Zed 远程终端连接与基础命令输出

命令输出:

wangxingjia

88dcb2233545

/home/wangxingjia/20235883_ai_practi

Linux 88dcb2233545 5.10.0-216.0.0.115.oe2203sp4.x86_64 #1 SMP Thu Jun 27 15:13:44 CST 2024 x86_64 x86_64 x86_64 GNU/Linux

说明:

  • whoami 输出当前登录用户 wangxingjia
  • hostname 输出容器/服务器主机名 88dcb2233545
  • pwd 输出当前工作目录 /home/wangxingjia/20235883_ai_practi
  • uname -a 输出系统内核信息,确认运行的是 Linux x86_64 架构。

Problem (vscode2): Local computer or remote Ubuntu?

(a) VS Code 安装在个人电脑上,为什么可以操作 Ubuntu 服务器中的文件?

因为 Remote-SSH 插件通过 SSH 协议在本地 VS Code 和远程 Ubuntu 服务器之间建立安全连接。VS Code 会把文件编辑、终端输入等操作请求发送到远程服务器上执行,再把结果返回显示在本地窗口。所以看起来像是在本地操作,实际文件和命令都在远程服务器上运行。

(b) 在远程终端中创建的文件夹,会出现在本地桌面上吗?

不会 远程终端运行在 Ubuntu 服务器上,mkdir 等命令创建的文件和目录都保存在远程服务器的文件系统中,不会同步到本地电脑的桌面上。

Problem (shell1): First command-line operations

在远程 Ubuntu 终端中完成目录创建任务,学号为 20235883,所以目录命名为 20235883_ai_practice

使用的命令:

# 查看当前所在目录

pwd

# 回到用户主目录

cd ~

# 创建个人实训目录

mkdir 20235883_ai_practice

# 进入该目录

cd 20235883_ai_practice

# 创建三个子文件夹

mkdir data src outputs

# 查看创建结果

ls

终端截图:

目录创建与 ls 查看结果

从截图可以看到,20235883_ai_practice 目录下成功创建了 datasrcoutputs 三个子文件夹。左侧文件树和终端 ls 输出都验证了这一点。

Problem (file1): Managing a small project directory

20235883_ai_practice 目录下完成文件创建、复制、查看与删除操作。

完整命令记录:

# 进入项目目录

wangxingjia@88dcb2233545:~$ cd 20235883_ai_practice/

# 1. 进入 src 文件夹

wangxingjia@88dcb2233545:~/20235883_ai_practice$ cd src

# 2. 创建 hello.py

wangxingjia@88dcb2233545:~/20235883_ai_practice/src$ touch hello.py

# 3. 向文件中写入内容(截图中使用 vim 编辑,也可用 echo 直接写入)

wangxingjia@88dcb2233545:~/20235883_ai_practice/src$ echo 'print("Hello, Ubuntu!")' > hello.py

# 查看写入结果

wangxingjia@88dcb2233545:~/20235883_ai_practice/src$ cat hello.py

print("Hello, Ubuntu!")

# 4. 返回 20235883_ai_practice 目录

wangxingjia@88dcb2233545:~/20235883_ai_practice/src$ cd ..

# 5. 将 src/hello.py 复制到 outputs/hello_backup.py

wangxingjia@88dcb2233545:~/20235883_ai_practice$ cp src/hello.py outputs/hello_backup.py

# 6. 查看 outputs/hello_backup.py 的内容

wangxingjia@88dcb2233545:~/20235883_ai_practice$ cat outputs/hello_backup.py

print("Hello, Ubuntu!")

# 7. 删除备份文件

wangxingjia@88dcb2233545:~/20235883_ai_practice$ rm outputs/hello_backup.py

# 确认 outputs 目录已清空

wangxingjia@88dcb2233545:~/20235883_ai_practice$ ls outputs/

# 原文件仍在 src 中

wangxingjia@88dcb2233545:~/20235883_ai_practice$ cat src/hello.py

print("Hello, Ubuntu!")

终端截图:

file1 文件管理操作

cp、mv、rm 三个命令的区别

命令 全称 作用 原文件是否保留
cp copy 复制文件或目录,生成一份副本 保留,原文件仍在原处
mv move 移动文件或目录的位置,也可用于重命名 不保留,原位置文件消失
rm remove 删除文件或目录 删除后不可恢复(无回收站)
  • cp:常用于备份、复制文件到另一个目录,或在同一目录下生成同名/异名副本。例如 cp src/hello.py outputs/hello_backup.py 就是在 outputs 目录下生成 hello.py 的备份。
  • mv:用于移动文件位置或修改文件名。例如 mv src/hello.py outputs/hello.py 会把原文件从 src 移到 outputsmv hello.py hi.py 则是重命名。
  • rm:用于清理不再需要的文件或目录,执行后文件通常直接被移除,无法通过图形界面的“回收站”找回,因此删除前务必确认路径正确,尤其是使用 rm -r 递归删除目录时更要谨慎。

Problem (apt1): Installing basic tools

在 Ubuntu 中更新软件源并安装 tree,然后用 tree 查看 20235883_ai_practice 的目录结构。

完整命令记录:

# 1. 更新软件源

wangxingjia@88dcb2233545:~$ sudo apt update

# 2. 安装 tree

wangxingjia@88dcb2233545:~$ sudo apt install tree

# 3. 进入项目目录

wangxingjia@88dcb2233545:~$ cd 20235883_ai_practice

# 4. 运行 tree 查看目录结构

wangxingjia@88dcb2233545:~/20235883_ai_practice$ tree

.

├── Miniconda3-latest-Linux-x86_64.sh

├── data

├── outputs

└── src

└── hello.py

3 directories, 2 files

终端截图:

apt1 tree 输出

tree 输出显示 20235883_ai_practice 目录下包含 dataoutputssrc 三个子目录,以及 src/hello.pyMiniconda3-latest-Linux-x86_64.sh 两个文件,共 3 directories, 2 files

apt 和 pip 的区别

  • apt 是 Ubuntu/Debian 系统级的包管理器,用于安装操作系统层面的软件和工具(如 treegitpython3),通常需要 sudo 权限,管理软件包及其系统依赖。
  • pip 是 Python 专用的包管理器,用于安装 Python 第三方库(如 numpytorchrequests),通常在虚拟环境或 Conda 环境中使用,管理的是 Python 项目依赖。

简单来说:apt 管系统软件,pip 管 Python 库apt 面向整个系统,需要管理员权限,而 pip 更适合在隔离的 Python 环境中安装项目所需的库。

Problem (miniconda1): Installing Miniconda

在远程 Ubuntu 服务器中安装 Miniconda,完成初始化并检查安装结果。

完整命令记录:

# 1. 找到课程提供的 Miniconda 安装包

wangxingjia@88dcb2233545:~$ ls 20235883_ai_practice/

Miniconda3-latest-Linux-x86_64.sh data outputs src

# 2. 运行安装包(按提示 Enter 阅读协议、yes 同意、默认安装路径)

wangxingjia@88dcb2233545:~$ bash 20235883_ai_practice/Miniconda3-latest-Linux-x86_64.sh

# 3. 安装完成后,重新加载 shell 配置,使 conda 命令生效

wangxingjia@88dcb2233545:~$ source ~/.bashrc

# 4. 检查 conda 是否安装成功

wangxingjia@88dcb2233545:~/20235883_ai_practice$ conda --version

conda 26.3.2

# 5. 查看当前 Conda 环境列表

wangxingjia@88dcb2233545:~/20235883_ai_practice$ conda env list

# conda environments:

#

# * -> active

# + -> frozen

#

base /home/wangxingjia/miniconda3

# 6. 关闭自动激活 base 环境

wangxingjia@88dcb2233545:~/20235883_ai_practice$ conda config --set auto_activate_base false

终端截图:

miniconda1 安装与版本检查

(a) 为什么不建议直接把所有依赖安装到 base 环境中?

不建议把所有依赖都安装到 base 环境中,因为 base 是 Conda 的默认环境,所有项目共用会导致不同项目的依赖版本冲突,也不利于环境的复现和隔离。最佳实践是为每个项目单独创建一个虚拟环境,安装该项目所需的特定版本依赖。

(b) Miniconda 安装在 Ubuntu 服务器中,还是安装在本地个人电脑中?

安装在 Ubuntu 服务器中。 因为安装命令是在远程终端里执行的,安装路径 /home/wangxingjia/miniconda3 也位于远程 Ubuntu 服务器的文件系统上,本地个人电脑只是通过 Zed/VS Code Remote-SSH 远程操作。

(c) source ~/.bashrc 的作用是什么?

source ~/.bashrc 的作用是重新加载当前 shell 的配置文件。Miniconda 安装程序会在 ~/.bashrc 末尾写入 conda 的初始化脚本(包括把 conda 加入 PATH、注册 shell 函数等)。执行 source ~/.bashrc 后,这些修改会立即在当前终端生效,无需重新登录或新开终端,所以 conda --version 等命令才能被识别。

Problem (conda1): Understanding Conda and pip

(a) Conda 环境解决了什么问题?

Conda 环境主要解决了 Python 项目之间的依赖冲突和环境隔离 问题。不同项目可能依赖同一个库的不同版本,如果所有包都安装到同一个环境中,很容易造成版本不兼容、项目无法运行的情况。通过为每个项目创建独立的 Conda 环境,可以让各项目的依赖互不干扰,也便于环境的迁移和复现。

(b) pip install 安装的包一定属于整个 Ubuntu 系统吗?

不一定。 pip 安装包的位置取决于当前激活的是哪个 Python 解释器。激活某个 Conda 环境后,再使用 pip install 安装的包会被安装到该 Conda 环境对应的 site-packages 目录中(例如 /home/wangxingjia/miniconda3/envs/<env_name>/lib/pythonX.X/site-packages/),而不会影响整个 Ubuntu 系统的 Python 环境。

(c) 请解释 Ubuntu、Miniconda、Conda environment、pip 之间的层级关系

四者的层级关系可以概括为:Ubuntu 是操作系统层,提供底层的运行环境和系统级包管理工具 aptMiniconda 是安装在 Ubuntu 上的一个 Python 发行版与环境管理工具,它自带 conda 和基础 Python;Conda environment 是 Miniconda 创建的多个相互隔离的 Python 运行环境,每个环境拥有独立的解释器和依赖;pip 则是在某个 Conda 环境(或系统 Python)内部安装、管理 Python 第三方库的工具。因此,层级关系是:Ubuntu 承载 Miniconda,Miniconda 管理多个 Conda environment,每个 environment 中可以使用 pip 安装独立的 Python 包。

Problem (env1): Building a Conda inference environment

创建并配置名为 ai_infer 的 Conda 环境,用于后续模型推理实验。

完整命令记录:

# 1. 创建 ai_infer 环境,指定 Python 3.10

wangxingjia@88dcb2233545:~$ conda create -n ai_infer python=3.10

# 2. 激活环境

wangxingjia@88dcb2233545:~$ conda activate ai_infer

# 3. 检查 Python 版本

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ python --version

Python 3.10.20

# 4. 检查 pip 版本

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ pip --version

pip 26.1.1 from /home/wangxingjia/miniconda3/envs/ai_infer/lib/python3.10/site-packages/pip (python 3.10)

# 5. 安装 numpy 和 torch

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ pip install numpy torch

# 6. 检查 numpy 和 torch 是否安装成功

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ python -c "import numpy; print(numpy.__version__)"

2.2.6

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ python -c "import torch; print(torch.__version__)"

# torch 成功导入并输出版本号

# 7. 确认当前 Python 来自 ai_infer 环境

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ which python

/home/wangxingjia/miniconda3/envs/ai_infer/bin/python

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ which pip

/home/wangxingjia/miniconda3/envs/ai_infer/bin/pip

终端截图:

env1 ai_infer 环境配置

如何判断当前是否已经进入正确的 Conda 环境?

可以通过以下几点确认当前已进入 ai_infer 环境:

  1. 提示符前缀:终端命令行前出现 (ai_infer) 标识,例如 (ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$
  2. which python 路径:输出为 /home/wangxingjia/miniconda3/envs/ai_infer/bin/python,而不是系统 Python 或 base 环境的路径。
  3. Python 版本python --version 输出 Python 3.10.20,与创建环境时指定的版本一致。
  4. pip --version 路径:同样指向 ai_infer 环境目录下的 pip,说明安装的包会进入该环境。

Problem (infer1): First model inference

(a) 运行 inference.py

src/inference.py 的代码如下:

import torch

x = torch.tensor([[1.0, 2.0, 3.0]])

w = torch.tensor([[0.2], [0.5], [0.3]])

y = x @ w

print("Input:", x)

print("Weight:", w)

print("Output:", y)

运行命令与输出:

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ cd src

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice/src$ python inference.py

Input: tensor([[1., 2., 3.]])

Weight: tensor([[0.2000],

[0.5000],

[0.3000]])

Output: tensor([[2.1000]])

终端截图:

infer1 运行 inference.py

生成的 output.txt 内容:

Input: tensor([[1., 2., 3.]])

Weight: tensor([[0.2000],

[0.5000],

[0.3000]])

Output: tensor([[2.1000]])

(b) 解释 x @ w 的含义

x @ w 是 PyTorch 中的矩阵乘法运算符,表示将输入张量 x 与权重张量 w 相乘。在这个简单推理示例中,它计算输入特征与对应权重的加权和:把每个输入元素乘以其权重后求和,得到模型的输出。这是神经网络中最基本的线性变换操作,模拟了一个没有激活函数的单层线性神经元。

(c) 修改输入并再次运行

inference.py 中的输入改为:

x = torch.tensor([[2.0, 1.0, 4.0]])

再次运行:

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice/src$ python inference.py

Input: tensor([[2., 1., 4.]])

Weight: tensor([[0.2000],

[0.5000],

[0.3000]])

Output: tensor([[2.1000]])

终端截图:

infer1 修改输入后运行

输出变化说明

从数值上看,输出仍然是 tensor([[2.1000]])没有发生变化。这是因为新的输入 [2.0, 1.0, 4.0] 与权重 [0.2, 0.5, 0.3] 的加权和为:

2.0 × 0.2 + 1.0 × 0.5 + 4.0 × 0.3 = 0.4 + 0.5 + 1.2 = 2.1

恰好与原输入 [1.0, 2.0, 3.0] 的加权和:

1.0 × 0.2 + 2.0 × 0.5 + 3.0 × 0.3 = 0.2 + 1.0 + 0.9 = 2.1

相等。因此,虽然输入数据变了,但权重保持不变,且新输入与权重的点积恰好相同,所以最终输出没有变化。这也说明模型输出由输入和权重共同决定,改变输入不一定总是改变输出。

Problem (advanced1): Optional profiling with Scalene

本题为可选进阶题,使用 Scalene 分析并优化一个简单的神经网络前向传播程序。

1. 在 ai_infer 环境中安装 Scalene

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ pip install scalene

2. 编写并运行 src/slow_nn.py

import time

import torch

def slow_forward(x, w1, b1, w2, b2):

outputs = []

for i in range(x.shape[0]):

h = torch.relu(x[i] @ w1 + b1)

y = h @ w2 + b2

outputs.append(y)

return torch.stack(outputs)

def main():

torch.manual_seed(0)

batch_size = 4096

input_dim = 256

hidden_dim = 512

output_dim = 10

steps = 20

x = torch.randn(batch_size, input_dim)

w1 = torch.randn(input_dim, hidden_dim)

b1 = torch.randn(hidden_dim)

w2 = torch.randn(hidden_dim, output_dim)

b2 = torch.randn(output_dim)

start = time.perf_counter()

for _ in range(steps):

y = slow_forward(x, w1, b1, w2, b2)

end = time.perf_counter()

print("Output shape:", y.shape)

print("Elapsed seconds:", end - start)

if __name__ == "__main__":

main()

运行结果:

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ python src/slow_nn.py

Output shape: torch.Size([4096, 10])

Elapsed seconds: 48.69992172002094

3. 编写并运行优化后的 src/fast_nn.py

import time

import torch

def fast_forward(x, w1, b1, w2, b2):

h = torch.relu(x @ w1 + b1)

y = h @ w2 + b2

return y

def main():

torch.manual_seed(0)

batch_size = 4096

input_dim = 256

hidden_dim = 512

output_dim = 10

steps = 20

x = torch.randn(batch_size, input_dim)

w1 = torch.randn(input_dim, hidden_dim)

b1 = torch.randn(hidden_dim)

w2 = torch.randn(hidden_dim, output_dim)

b2 = torch.randn(output_dim)

start = time.perf_counter()

for _ in range(steps):

y = fast_forward(x, w1, b1, w2, b2)

end = time.perf_counter()

print("Output shape:", y.shape)

print("Elapsed seconds:", end - start)

if __name__ == "__main__":

main()

运行结果:

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ python src/fast_nn.py

Output shape: torch.Size([4096, 10])

Elapsed seconds: 2.382431996986627

4. 使用 Scalene 分析

尝试使用 python -m scalene 运行 Scalene:

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ python -m scalene src/fast_nn.py

Scalene: error: 'src/fast_nn.py' is not a valid command.

Did you mean: scalene run src/fast_nn.py

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practice$ python -m scalene src/slow_nn.py

Scalene: error: 'src/slow_nn.py' is not a valid command.

Did you mean: scalene run src/slow_nn.py

Scalene 2.3.0 需要通过子命令 scalene run <脚本> 来运行,而不是 python -m scalene <脚本>。正确用法如下:

scalene run src/slow_nn.py

scalene run src/fast_nn.py

终端截图:

advanced1 Scalene 帮助与报错(上)

advanced1 Scalene 帮助与报错(下)

(a) slow_nn.py 的主要性能瓶颈在哪里?

slow_nn.py 的主要性能瓶颈在于 slow_forward 函数中的 Python 级 for 循环。程序逐条遍历 batch 中的 4096 个样本,每次只对一个样本做矩阵乘法,导致大量时间消耗在 Python 解释器循环调度、张量索引和小规模核函数启动开销上,无法充分利用 PyTorch 底层优化的批量矩阵运算能力。

(b) 采用了什么优化思路?

优化思路是把逐条样本的循环改为 batch 矩阵计算。在 fast_forward 中,直接用 x @ w1 对整个 batch 进行矩阵乘法,配合广播机制一次性完成 ReLU 和第二层线性变换。这样 PyTorch 可以调用高度优化的 BLAS/MKL 底层实现,充分利用 CPU 的 SIMD 和并行能力,减少 Python 层循环开销。

(c) 优化前后是否有明显提升?

有明显提升。 slow_nn.py 运行 20 步共耗时约 48.70 秒,而 fast_nn.py 仅耗时约 2.38 秒,速度提升了约 20 倍。两者输出形状完全一致(torch.Size([4096, 10])),说明计算结果等价,但 batch 化矩阵运算显著减少了运行时间。Scalene 若按正确命令运行,预计会显示 slow_nn.py 的 Python 循环部分占用绝大部分 CPU 时间,而 fast_nn.py 的时间主要集中在 PyTorch 的底层 C++ 矩阵乘法核上,Python 解释器开销大幅减少。

Problem (export1): Exporting the environment

将配置好的 ai_infer 环境导出为 environment.yml,便于后续复现和共享。

完整命令记录:

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practi$ conda env export > environment.yml

(ai_infer) wangxingjia@88dcb2233545:~/20235883_ai_practi$ cat environment.yml

导出的 environment.yml 内容如下:

name: ai_infer

channels:

- defaults

dependencies:

- _libgcc_mutex=0.1=main

- _openmp_mutex=5.1=52_gnu

- bzip2=1.0.8=h5eee18b_6

- ca-certificates=2026.5.14=h06a4308_0

- ld_impl_linux-64=2.44=h9e0c5a2_3

- libexpat=2.8.1=h7354ed3_1

- libffi=3.4.8=h06d3fd0_3

- libgcc=15.2.0=h69a1729_8

- libgcc-ng=15.2.0=h166f726_8

- libnsl=2.0.0=h5eee18b_0

- libstdcxx=15.2.0=h39759b7_8

- libuuid=1.41.5=h5eee18b_0

- libxcb=1.17.0=h9b100fa_0

- libzlib=1.3.2=h47b2149_0

- ncurses=6.5=h7934f7d_0

- openssl=3.5.7=h1b28b03_0

- packaging=26.0=py310h06a4308_0

- pip=26.1.1=pyhc872135_1

- pthread-stubs=0.3=h0ce48e5_1

- python=3.10.20=h17756b0_1

- readline=8.3=hc2a1206_0

- sqlite=3.53.2=h795bf6d_0

- tk=8.6.15=h54e0aa7_0

- tzdata=2026b=he532380_0

- wheel=0.47.0=py310h06a4308_0

- xorg-libx11=1.8.12=h9b100fa_1

- xorg-libxau=1.0.12=h9b100fa_0

- xorg-libxdmcp=1.1.5=h9b100fa_0

- xorg-xorgproto=2024.1=h5eee18b_1

- xz=5.8.2=h448239c_0

- zlib=1.3.2=h47b2149_0

- pip:

- annotated-doc==0.0.4

- annotated-types==0.7.0

- anyio==4.14.0

- certifi==2026.6.17

- click==8.4.1

- cloudpickle==3.1.2

- cuda-bindings==13.3.1

- cuda-pathfinder==1.5.5

- cuda-toolkit==13.0.2

- exceptiongroup==1.3.1

- filelock==3.29.4

- fsspec==2026.6.0

- h11==0.16.0

- hf-xet==1.5.1

- httpcore==1.0.9

- httpx==0.28.1

- huggingface-hub==1.20.1

- idna==3.18

- jinja2==3.1.6

- markdown-it-py==4.2.0

- markupsafe==3.0.3

- mdurl==0.1.2

- mpmath==1.3.0

- networkx==3.4.2

- numpy==2.2.6

- nvidia-cublas==13.1.1.3

- nvidia-cuda-cupti==13.0.85

- nvidia-cuda-nvrtc==13.0.88

- nvidia-cuda-runtime==13.0.96

- nvidia-cudnn-cu13==9.20.0.48

- nvidia-cufft==12.0.0.61

- nvidia-cufile==1.15.1.6

- nvidia-curand==10.4.0.35

- nvidia-cusolver==12.0.4.66

- nvidia-cusparse==12.6.3.3

- nvidia-cusparselt-cu13==0.8.1

- nvidia-ml-py==13.610.43

- nvidia-nccl-cu13==2.29.7

- nvidia-nvjitlink==13.0.88

- nvidia-nvshmem-cu13==3.4.5

- nvidia-nvtx==13.0.85

- psutil==7.2.2

- pydantic==2.13.4

- pydantic-core==2.46.4

- pygments==2.20.0

- pyyaml==6.0.3

- regex==2026.5.9

- rich==15.0.0

- safetensors==0.8.0

- scalene==2.3.0

- setuptools==81.0.0

- shellingham==1.5.4

- sympy==1.14.0

- tokenizers==0.22.2

- torch==2.12.1

- tqdm==4.68.3

- transformers==5.12.1

- triton==3.7.1

- typer==0.25.1

- typing-extensions==4.15.0

- typing-inspection==0.4.2

prefix: /home/wangxingjia/miniconda3/envs/ai_infer

文件中记录了哪些信息?

environment.yml 主要记录了以下几类信息:

  • name:环境名称 ai_infer
  • channels:Conda 包来源渠道,这里使用 defaults
  • dependencies:通过 Conda 安装的依赖包及其精确版本和构建号,例如 python=3.10.20pip=26.1.1
  • pip: 子项:通过 pip 安装的 Python 库及其版本,例如 numpy==2.2.6torch==2.12.1scalene==2.3.0transformers==5.12.1
  • prefix:环境在文件系统中的绝对路径 /home/wangxingjia/miniconda3/envs/ai_infer

为什么 AI 项目需要保存环境配置?

AI 项目通常依赖大量第三方库,且这些库对版本非常敏感(例如 PyTorch、CUDA、transformers 之间需要严格匹配)。保存 environment.yml 可以精确记录项目运行所需的所有依赖及其版本,便于在另一台机器或 teammate 的环境中通过 conda env create -f environment.yml 一键复现相同环境,避免“在我电脑上能跑”的问题,也方便项目迁移、部署和长期维护。

Problem (debug1): Debugging a missing package

遇到 ModuleNotFoundError: No module named 'torch' 怎么办?

这个错误表示当前 Python 解释器在搜索路径中找不到名为 torch 的模块。常见原因包括:没有安装 PyTorch、安装在了错误的 Conda/虚拟环境中、当前未激活正确的环境,或者使用了系统 Python 而非项目环境内的 Python。排查时应先确认自己是否在正确的环境中,可以依次执行 which pythonpython --versionconda env list 查看当前 Python 路径、版本和可用环境;然后执行 pip list | grep torchpython -c "import torch" 确认 torch 是否已安装。如果当前环境不对,应使用 conda activate ai_infer 切换到项目环境;如果 torch 未安装,则在该环境中执行 pip install torch 进行安装;若版本冲突,可尝试指定兼容版本,或根据 environment.yml 重新创建环境。养成在进入项目前激活对应环境的习惯,是避免此类问题的最佳做法。

总结

Day1 从零起步完成了从远程连接到模型推理的全流程搭建,核心收获如下:

  1. 远程开发:通过 Remote-SSH 连接服务器,实现“本地写代码、远程跑任务“
  2. Linux 命令行基础:掌握了 cdmkdircpmvrm 等文件操作,以及 apttree 等工具的使用。
  3. 环境管理:用 Miniconda + Conda 虚拟环境隔离项目依赖,基本告别“在我电脑上能跑“的问题。
  4. 推理实战:用 PyTorch 写了一个单层线性变换 x @ w,并对比了逐条循环与 batch 矩阵计算的性能差距。

其实大部分都会,除了PyTorch,还得捡起来线性代数的知识才行