> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-zh/xun-lian/jupyter-ml-training.md).

# Jupyter ML 训练

在 Clore.ai 上搭建支持 GPU 的 JupyterLab 用于机器学习训练

设置带 GPU 支持的 JupyterLab，用于机器学习实验和模型训练。

{% hint style="success" %}
所有示例都可以在通过以下方式租用的 GPU 服务器上运行 [CLORE.AI 市场](https://clore.ai/marketplace).
{% endhint %}

## 服务器要求

| 参数   | 最低      | 推荐       |
| ---- | ------- | -------- |
| 内存   | 16GB    | 32GB以上   |
| 显存   | 8GB     | 16GB+    |
| 网络   | 200Mbps | 500Mbps+ |
| 启动时间 | 2-3分钟   | -        |

{% hint style="info" %}
JupyterLab 本身很轻量。请根据你的训练工作负载需求选择 GPU 和 RAM。
{% endhint %}

## 快速部署

**Docker 镜像：**

```
pytorch/pytorch:2.11.0-cuda12.8-cudnn9-runtime
```

**端口：**

```
22/tcp
8888/http
6006/http
```

**环境变量：**

```
JUPYTER_TOKEN=your_secure_token_here
```

**命令：**

```bash
pip install jupyterlab tensorboard && \\
jupyter lab --ip=0.0.0.0 --port=8888 --allow-root --NotebookApp.token='your_secure_token_here'
```

## 访问你的服务

部署后，找到你的 `http_pub` URL 在 **我的订单**:

1. 前往 **我的订单** 页面
2. 点击你的订单
3. 找到 `http_pub` URL（例如， `abc123.clorecloud.net`)

使用 `https://YOUR_HTTP_PUB_URL` 替代 `localhost` 在下面的示例中。

### 验证是否正常工作

```bash
# 检查 JupyterLab 是否可访问
curl https://your-http-pub.clorecloud.net/

# 使用令牌访问
# https://your-http-pub.clorecloud.net/?token=your_secure_token_here
```

{% hint style="warning" %}
如果你收到 HTTP 502，请等待 2-3 分钟——服务正在安装依赖。
{% endhint %}

## 在 CLORE.AI 上租用

1. 访问 [CLORE.AI 市场](https://clore.ai/marketplace)
2. 按 GPU 类型、VRAM 和价格筛选
3. 选择 **按需** （固定费率）或 **竞价** （出价）
4. 配置你的订单：
   * 选择 Docker 镜像
   * 设置端口（SSH 用 TCP，Web UI 用 HTTP）
   * 如有需要，添加环境变量
   * 输入启动命令
5. 选择支付方式： **CLORE**, **BTC**，或 **USDT/USDC**
6. 创建订单并等待部署

### 访问你的服务器

* 在以下位置查找连接信息 **我的订单**
* Web 界面：使用 HTTP 端口 URL
* SSH： `ssh -p <port> root@<proxy-address>`

## 访问 Jupyter

1. 等待部署完成
2. 查找 8888 端口映射
3. 打开： `http://<proxy>:<port>?token=your_secure_token_here`

## 预配置的 ML 镜像

对于完整的 ML 环境：

**镜像：**

```
quay.io/jupyter/pytorch-notebook:cuda12-pytorch-2.11.0
```

或者构建自定义镜像：

```dockerfile
FROM pytorch/pytorch:2.11.0-cuda12.8-cudnn9-runtime

RUN pip install --no-cache-dir \
    jupyterlab \\
    numpy pandas matplotlib seaborn \\
    scikit-learn \\
    transformers datasets accelerate \\
    tensorboard wandb \\
    opencv-python pillow \\
    tqdm rich

EXPOSE 8888 6006

CMD ["jupyter", "lab", "--ip=0.0.0.0", "--allow-root"]
```

## 必备库

### 在 Jupyter 中安装

```python
!pip install transformers datasets accelerate bitsandbytes
!pip install wandb tensorboard
!pip install scikit-learn xgboost lightgbm
!pip install opencv-python albumentations
```

### 创建 requirements.txt

```

# ML 框架
torch>=2.1.0
torchvision
torchaudio

# NLP
transformers>=4.36.0
datasets
tokenizers
sentencepiece

# 训练
accelerate
bitsandbytes
peft
trl

# 监控
wandb
tensorboard

# 数据
numpy
pandas
matplotlib
seaborn
scikit-learn

# 计算机视觉
opencv-python
pillow
albumentations
```

## 训练示例

### PyTorch 图像分类

```python
import torch
import torch.nn as nn
import torchvision
from torchvision import transforms
from torch.utils.data import DataLoader

# 检查 GPU
print(f"GPU: {torch.cuda.get_device_name(0)}")
print(f"内存: {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f} GB")

# 加载数据
transform = transforms.Compose([
    transforms.Resize(224),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

train_data = torchvision.datasets.CIFAR10(
    root='./data', train=True, download=True, transform=transform
)
train_loader = DataLoader(train_data, batch_size=64, shuffle=True, num_workers=4)

# 模型
model = torchvision.models.resnet18(pretrained=True)
model.fc = nn.Linear(512, 10)
model = model.cuda()

# 训练
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
criterion = nn.CrossEntropyLoss()

for epoch in range(10):
    model.train()
    for images, labels in train_loader:
        images, labels = images.cuda(), labels.cuda()

        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

    print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")

# 保存模型
torch.save(model.state_dict(), 'model.pth')
```

### HuggingFace 文本分类

```python
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from transformers import TrainingArguments, Trainer
from datasets import load_dataset
import numpy as np

# 加载数据集
dataset = load_dataset("imdb")

# 加载模型
model_name = "distilbert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)

# 分词
def tokenize(examples):
    return tokenizer(examples["text"], padding="max_length", truncation=True)

tokenized = dataset.map(tokenize, batched=True)

# 训练
training_args = TrainingArguments(
    output_dir="./results",
    num_train_epochs=3,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=64,
    warmup_steps=500,
    weight_decay=0.01,
    logging_dir="./logs",
    logging_steps=100,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized["train"],
    eval_dataset=tokenized["test"],
)

trainer.train()
trainer.save_model("./best_model")
```

### 使用 LoRA 微调 LLM

```python
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from datasets import load_dataset
from trl import SFTTrainer
import torch

# 使用 4 位量化加载模型
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.float16,
)

model = AutoModelForCausalLM.from_pretrained(
    "mistralai/Mistral-7B-v0.1",
    quantization_config=bnb_config,
    device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")
tokenizer.pad_token = tokenizer.eos_token

# 配置 LoRA
lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

model = prepare_model_for_kbit_training(model)
model = get_peft_model(model, lora_config)

# 加载数据集
dataset = load_dataset("timdettmers/openassistant-guanaco")

# 训练
trainer = SFTTrainer(
    model=model,
    train_dataset=dataset["train"],
    dataset_text_field="text",
    max_seq_length=512,
    tokenizer=tokenizer,
    args=TrainingArguments(
        output_dir="./lora_output",
        num_train_epochs=1,
        per_device_train_batch_size=4,
        gradient_accumulation_steps=4,
        learning_rate=2e-4,
        fp16=True,
        logging_steps=10,
        save_steps=100,
    ),
)

trainer.train()
trainer.save_model("./final_lora")
```

## TensorBoard 集成

### 启动 TensorBoard

```python
%load_ext tensorboard
%tensorboard --logdir ./logs --port 6006 --bind_all
```

或者通过终端：

```bash
tensorboard --logdir ./logs --port 6006 --bind_all &
```

### 记录训练指标

```python
from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter('./logs')

for epoch in range(epochs):
    # ... 训练循环 ...
    writer.add_scalar('Loss/train', train_loss, epoch)
    writer.add_scalar('Loss/val', val_loss, epoch)
    writer.add_scalar('Accuracy/val', accuracy, epoch)

writer.close()
```

## Weights & Biases 集成

```python
import wandb

wandb.init(project="my-project", name="experiment-1")

# 记录指标
wandb.log({"loss": loss, "accuracy": acc})

# 记录模型
wandb.save("model.pth")

# 完成
wandb.finish()
```

## 数据管理

### 下载数据集

```python

# HuggingFace 数据集
from datasets import load_dataset
dataset = load_dataset("squad")

# Kaggle 数据集
!pip install kaggle
!kaggle datasets download -d username/dataset-name

# 直接下载
!wget https://example.com/data.zip
!unzip data.zip
```

### 挂载云存储

```python

# S3
!pip install boto3
import boto3
s3 = boto3.client('s3')
s3.download_file('bucket', 'key', 'local_path')

# Google Cloud
!pip install google-cloud-storage
from google.cloud import storage
client = storage.Client()
bucket = client.bucket('my-bucket')
blob = bucket.blob('data.zip')
blob.download_to_filename('data.zip')
```

## 保存工作

### 保存到外部存储

```python

# 将模型保存到 S3
import boto3
s3 = boto3.client('s3',
    aws_access_key_id='YOUR_KEY',
    aws_secret_access_key='YOUR_SECRET'
)
s3.upload_file('model.pth', 'my-bucket', 'models/model.pth')
```

### 会话结束前

```bash

# 下载重要文件
scp -P <port> root@<host>:/workspace/model.pth ./
scp -P <port> -r root@<host>:/workspace/results/ ./results/
```

## 多 GPU 训练

```python
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel

# 检查 GPU
print(f"可用 GPU 数量: {torch.cuda.device_count()}")

# DataParallel（简单）
model = nn.DataParallel(model)

# DistributedDataParallel（更好）

# 启动方式：torchrun --nproc_per_node=4 train.py
dist.init_process_group("nccl")
model = DistributedDataParallel(model)
```

## 性能提示

### 内存优化

```python

# 梯度检查点
model.gradient_checkpointing_enable()

# 混合精度
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()

with autocast():
    output = model(input)
    loss = criterion(output, target)

scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
```

### 数据加载

```python

# 更快的数据加载
loader = DataLoader(
    dataset,
    batch_size=64,
    num_workers=8,      # 使用多个工作线程
    pin_memory=True,    # 更快的 GPU 传输
    prefetch_factor=2   # 预取批次
)
```

## 故障排查

## 成本估算

CLORE.AI 市场常见费率（截至 2024 年）：

| GPU       | 小时费率    | 日费率     | 4 小时会话  |
| --------- | ------- | ------- | ------- |
| RTX 3060  | \~$0.03 | \~$0.70 | \~$0.12 |
| RTX 3090  | \~$0.06 | \~$1.50 | \~$0.25 |
| RTX 4090  | \~$0.10 | \~$2.30 | \~$0.40 |
| A100 40GB | \~$0.17 | \~$4.00 | \~$0.70 |
| A100 80GB | \~$0.25 | \~$6.00 | \~$1.00 |

*价格因提供商和需求而异。请查看* [*CLORE.AI 市场*](https://clore.ai/marketplace) *以获取当前费率。*

**节省费用：**

* 使用 **竞价** 可中断工作市场——约三分之一的服务器将现货价格定得低于按需价格（中位数约优惠 13%），其余则与按需价格持平
* 使用 **CLORE** 代币支付
* 比较不同提供商的价格


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-zh/xun-lian/jupyter-ml-training.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
