主题
Jupyter Notebook GPU 环境部署指南
适用环境: K3s + HAMi vGPU 集群
最后更新: 2026-08-22
目录
1. Jupyter 简介
Jupyter Notebook 是一个交互式计算环境,广泛用于数据探索、机器学习、可视化和教学演示。
架构示意
浏览器 → Jupyter Server (HTTP/WebSocket) → Python Kernel → GPU (CUDA)
↓
Notebook 文件 (.ipynb)版本选择
| 发行版 | 适用场景 | 镜像大小 |
|---|---|---|
jupyter/base-notebook | 纯 Python 数据分析 | ~500MB |
jupyter/scipy-notebook | 科学计算 | ~1.2GB |
jupyter/tensorflow-notebook | TensorFlow 深度学习 | ~4GB |
jupyter/pytorch-notebook | PyTorch 深度学习 | ~5GB |
2. 镜像选择与国内配置
2.1 推荐镜像
bash
# PyTorch GPU 版本(推荐)
jupyter/pytorch-notebook:cuda12-latest2.2 国内拉取与推送
bash
# 从华为云镜像拉取
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/jupyter/pytorch-notebook:cuda12-latest
# 重新打标签
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/jupyter/pytorch-notebook:cuda12-latest \
jupyter/pytorch-notebook:cuda12-latest
# 推送到本地 Registry
REGISTRY="117.50.188.237:30000"
docker tag jupyter/pytorch-notebook:cuda12-latest \
${REGISTRY}/jupyter/pytorch-notebook:cuda12-latest
docker push ${REGISTRY}/jupyter/pytorch-notebook:cuda12-latest2.3 pip 国内源
在 Notebook 第一个 Cell 中执行:
python
import subprocess
subprocess.run(["pip", "config", "set", "global.index-url",
"https://pypi.tuna.tsinghua.edu.cn/simple"])2.4 HuggingFace 镜像
yaml
env:
- name: HF_ENDPOINT
value: "https://hf-mirror.com"
- name: HF_HOME
value: "/home/jovyan/.cache/huggingface"
---
## 3. 部署方案
### 3.1 单用户 Deployment
```yaml
# jupyter-gpu.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jupyter-gpu
spec:
replicas: 1
selector:
matchLabels:
app: jupyter-gpu
template:
metadata:
labels:
app: jupyter-gpu
spec:
schedulerName: hami-scheduler
nodeSelector:
kubernetes.io/hostname: "10-60-205-41"
containers:
- name: jupyter
image: 117.50.188.237:30000/jupyter/pytorch-notebook:cuda12-latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8888
name: http
env:
- name: JUPYTER_TOKEN
value: "your-secure-password"
- name: HF_ENDPOINT
value: "https://hf-mirror.com"
- name: GRANT_SUDO
value: "yes"
resources:
requests:
cpu: "1"
memory: "4Gi"
nvidia.com/gpu: "1"
nvidia.com/gpumem: "6k"
limits:
cpu: "4"
memory: "8Gi"
nvidia.com/gpu: "1"
nvidia.com/gpumem: "6k"
volumeMounts:
- name: workspace
mountPath: /home/jovyan/work
- name: models
mountPath: /models
readOnly: true
- name: cache
mountPath: /home/jovyan/.cache
volumes:
- name: workspace
persistentVolumeClaim:
claimName: jupyter-workspace
- name: models
persistentVolumeClaim:
claimName: nfs-modelscope
readOnly: true
- name: cache
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: jupyter-gpu
spec:
selector:
app: jupyter-gpu
ports:
- port: 8888
targetPort: 8888
nodePort: 30888
type: NodePort3.2 持久化工作目录
yaml
# jupyter-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jupyter-workspace
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 50Gi3.3 部署命令
bash
kubectl apply -f jupyter-pvc.yaml
kubectl apply -f jupyter-gpu.yaml
kubectl get pods -o wide | grep jupyter
kubectl logs -f deploy/jupyter-gpu4. 访问与使用
4.1 获取访问地址
bash
# 方式一:NodePort
# http://<node-ip>:30888
# 方式二:kubectl port-forward(推荐)
kubectl port-forward svc/jupyter-gpu 8888:8888
# 访问 http://localhost:8888
# 方式三:Traefik Ingress4.2 登录
使用部署时设置的 JUPYTER_TOKEN 环境变量值登录。
4.3 Traefik Ingress 配置
yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: jupyter-ingress
spec:
entryPoints:
- web
routes:
- match: PathPrefix("/jupyter")
kind: Rule
services:
- name: jupyter-gpu
port: 8888
middlewares:
- name: jupyter-strip-prefix
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: jupyter-strip-prefix
spec:
stripPrefix:
prefixes:
- /jupyter访问:http://117.50.188.237/jupyter
5. 自定义环境
5.1 安装额外包
在 Notebook 第一个 Cell 中执行:
python
!pip install transformers datasets accelerate peft
!pip install matplotlib seaborn scikit-learn5.2 自定义 Dockerfile
dockerfile
FROM jupyter/pytorch-notebook:cuda12-latest
USER root
# 安装系统依赖
RUN apt-get update && apt-get install -y \
git vim htop \
&& rm -rf /var/lib/apt/lists/*
# 配置 pip 国内源
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 安装额外 Python 包
RUN pip install \
transformers datasets accelerate peft bitsandbytes \
matplotlib seaborn
USER $NB_UID构建并推送:
bash
docker build -t jupyter-custom:latest .
docker tag jupyter-custom:latest 117.50.188.237:30000/jupyter-custom:latest
docker push 117.50.188.237:30000/jupyter-custom:latest6. GPU 使用示例
6.1 PyTorch GPU 检测
python
import torch
print(f"PyTorch version: {torch.__version__}")
print(f"CUDA available: {torch.cuda.is_available()}")
print(f"CUDA version: {torch.version.cuda}")
print(f"GPU count: {torch.cuda.device_count()}")
if torch.cuda.is_available():
print(f"GPU name: {torch.cuda.get_device_name(0)}")
print(f"GPU memory: {torch.cuda.get_device_properties(0).total_memory / 1e9:.2f} GB")6.2 简单训练示例
python
import torch
import torch.nn as nn
import torch.optim as optim
# 创建简单模型
model = nn.Sequential(
nn.Linear(784, 128),
nn.ReLU(),
nn.Linear(128, 10)
).cuda()
# 创建虚拟数据
X = torch.randn(64, 784).cuda()
y = torch.randint(0, 10, (64,)).cuda()
# 训练
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
for epoch in range(10):
optimizer.zero_grad()
output = model(X)
loss = criterion(output, y)
loss.backward()
optimizer.step()
print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")
print("Training complete!")6.3 HuggingFace Transformers 示例
python
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
# 加载模型(使用本地路径)
model_path = "/models/Qwen/Qwen3-0.6B"
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(model_path).cuda()
# 生成文本
prompt = "人工智能的未来是"
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
outputs = model.generate(
**inputs,
max_new_tokens=100,
temperature=0.7,
do_sample=True
)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(response)6.4 显存监控
python
import torch
def print_gpu_memory():
if torch.cuda.is_available():
allocated = torch.cuda.memory_allocated() / 1024**3
reserved = torch.cuda.memory_reserved() / 1024**3
max_allocated = torch.cuda.max_memory_allocated() / 1024**3
print(f"Allocated: {allocated:.2f} GB")
print(f"Reserved: {reserved:.2f} GB")
print(f"Max Allocated: {max_allocated:.2f} GB")
print_gpu_memory()7. 运维指南
7.1 日志与监控
bash
# 查看 Jupyter 日志
kubectl logs -f deploy/jupyter-gpu
# 查看资源使用
kubectl top pod -l app=jupyter-gpu
# 查看 GPU 使用
kubectl exec -it $(kubectl get pod -l app=jupyter-gpu -o name) -- nvidia-smi7.2 数据备份
bash
# 导出工作目录
kubectl cp $(kubectl get pod -l app=jupyter-gpu -o jsonpath='{.items[0].metadata.name}'):/home/jovyan/work ./jupyter-backup
# 导入
kubectl cp ./jupyter-backup $(kubectl get pod -l app=jupyter-gpu -o jsonpath='{.items[0].metadata.name}'):/home/jovyan/work7.3 资源调整
bash
# 增加内存
kubectl patch deploy jupyter-gpu --type='json' \
-p='[{"op": "replace", "path": "/spec/template/spec/containers/0/resources/limits/memory", "value":"16Gi"}]'
# 增加 GPU 显存
kubectl patch deploy jupyter-gpu --type='json' \
-p='[{"op": "replace", "path": "/spec/template/spec/containers/0/resources/limits/nvidia.com~1gpumem", "value":"8k"}]'8. 故障排查
8.1 GPU 不可见
现象:torch.cuda.is_available() 返回 False
解决:确保使用 schedulerName: hami-scheduler 并请求 nvidia.com/gpumem
8.2 权限问题
PermissionError: [Errno 13] Permission denied解决:
yaml
env:
- name: GRANT_SUDO
value: "yes"
- name: CHOWN_HOME
value: "yes"8.3 Notebook 无法保存
Unexpected error while saving file解决:检查 PVC 挂载权限
bash
kubectl exec -it <pod-name> -- ls -la /home/jovyan/work8.4 内存不足 (OOM)
The kernel appears to have died. It will restart automatically.解决:增加 Pod 内存限制
yaml
resources:
limits:
memory: "16Gi"附录
A. 常用快捷键
| 快捷键 | 功能 |
|---|---|
Shift + Enter | 运行当前 Cell |
Esc + A | 在上方插入 Cell |
Esc + B | 在下方插入 Cell |
Esc + D + D | 删除 Cell |
Esc + M | 转为 Markdown |
Esc + Y | 转为 Code |
B. JupyterLab vs Notebook
| 特性 | Jupyter Notebook | JupyterLab |
|---|---|---|
| 界面 | 经典单页 | 现代多标签 |
| 多文件 | 不支持 | 支持 |
| 终端 | 不支持 | 支持 |
| 插件 | 有限 | 丰富 |
JupyterLab 已默认启用,访问时自动跳转。
文档版本: v1.0
更新时间: 2026-08-22
适用版本: Jupyter PyTorch CUDA 12