硬件配置

CPU :30核
内存:118GB
DCU :异构加速卡BW 128GB,2

安装步骤

1.检查配置(卡和磁盘空间)

:~# hy-smi

================================= System Management Interface ==================================
================================================================================================
HCU     Temp     AvgPwr     Perf     PwrCap     VRAM%      HCU%      Dec%      Enc%      Mode
0       52.0C    96.0W      auto     1000.0W    48%        0.0%      0.0%      0.0%      Normal
1       51.0C    75.0W      auto     1000.0W    51%        0.0%      0.0%      0.0%      Normal
================================================================================================
======================================== End of SMI Log ========================================

2.创建持久化目录

执行:

mkdir -p /root/private_data/llm/models
mkdir -p /root/private_data/llm/cache/huggingface
mkdir -p /root/private_data/llm/cache/modelscope
mkdir -p /root/private_data/llm/code
mkdir -p /root/private_data/llm/logs
mkdir -p /root/private_data/llm/offload

创建环境变量文件:

cat > /root/private_data/llm/env.sh <<'EOF'
export HF_HOME=/root/private_data/llm/cache/huggingface
export HUGGINGFACE_HUB_CACHE=/root/private_data/llm/cache/huggingface/hub
export TRANSFORMERS_CACHE=/root/private_data/llm/cache/huggingface/transformers
export MODELSCOPE_CACHE=/root/private_data/llm/cache/modelscope
export TOKENIZERS_PARALLELISM=false
EOF

加载环境变量:

source /root/private_data/llm/env.sh

查看是否生效:

echo "$HF_HOME"
echo "$MODELSCOPE_CACHE"

3.检查软件包

执行:

python3 - <<'PY'
packages = ["torch", "transformers", "accelerate", "modelscope", "safetensors"]

for name in packages:
    try:
        module = __import__(name)
        print(f"{name}: {getattr(module, '__version__', '已安装')}")
    except Exception as e:
        print(f"{name}: 未安装,{e}")
PY

缺少依赖时安装

可以先在 Notebook 的“工具面板”中切换国内 Pip 源,也可以执行:

python3 -m pip config set global.index-url >>https://pypi.tuna.tsinghua.edu.cn/simple

安装推理依赖:

python3 -m pip install -U \
"transformers>=4.46,<5" \
"accelerate>=1.0" \
modelscope \
safetensors \
sentencepiece

注意:不要重新安装或升级 torch。当前 PyTorch 是平台适配 DTK/BW 的版本,普通 PyPI 的 torch 可能覆盖平台版本。
安装后重新检查:

python3 - <<'PY'
import torch
import transformers
import accelerate
import modelscope

print("torch:", torch.__version__)
print("HIP/DTK:", torch.version.hip)
print("transformers:", transformers.__version__)
print("accelerate:", accelerate.__version__)
print("modelscope:", modelscope.__version__)
print("HCU count:", torch.cuda.device_count())
PY

确认 HCU count 仍然是 2

4.下载Qwen2.5-32B-Instruct

国内环境优先使用 ModelScope。

进入模型目录:

cd /root/private_data/llm/models

下载模型:

modelscope download \
  --model Qwen/Qwen2.5-32B-Instruct \
  --local_dir /root/private_data/llm/models/Qwen2.5-32B-Instruct

模型较大,下载过程中不要关闭 Notebook。
下载结束后检查:

du -sh /root/private_data/llm/models/Qwen2.5-32B-Instruct

查看主要文件:

ls -lh /root/private_data/llm/models/Qwen2.5-32B-Instruct | head -30

正常应包含类似文件:

config.json
tokenizer.json
tokenizer_config.json
generation_config.json
model-00001-of-xxxxx.safetensors
model.safetensors.index.json

5.创建双卡交互式推理程序

执行:

cat > /root/private_data/llm/code/chat_qwen32b.py <<'PY'
import os
import sys
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

MODEL_PATH = "/root/private_data/llm/models/Qwen2.5-32B-Instruct"

if not os.path.isdir(MODEL_PATH):
    raise FileNotFoundError(f"没有找到模型目录:{MODEL_PATH}")

if not torch.cuda.is_available():
    raise RuntimeError("当前 PyTorch 未识别到 HCU 加速卡")

if torch.cuda.device_count() < 2:
    raise RuntimeError(
        f"当前只识别到 {torch.cuda.device_count()} 张卡,需要检查资源配置"
    )

print("=" * 70)
print("正在加载模型")
print("模型路径:", MODEL_PATH)
print("PyTorch:", torch.__version__)
print("HIP/DTK:", torch.version.hip)
print("HCU数量:", torch.cuda.device_count())
print("=" * 70)

tokenizer = AutoTokenizer.from_pretrained(
    MODEL_PATH,
    trust_remote_code=True,
    use_fast=True,
)

# 给每张64GB卡留出一定运行空间。
max_memory = {
    0: "56GiB",
    1: "56GiB",
    "cpu": "90GiB",
}

model = AutoModelForCausalLM.from_pretrained(
    MODEL_PATH,
    torch_dtype=torch.bfloat16,
    device_map="auto",
    max_memory=max_memory,
    low_cpu_mem_usage=True,
    trust_remote_code=True,
    use_safetensors=True,
    attn_implementation="eager",
    offload_folder="/root/private_data/llm/offload",
)

model.eval()

print("\n模型加载完成。设备分配:")
if hasattr(model, "hf_device_map"):
    for module_name, device in model.hf_device_map.items():
        print(f"{module_name}: {device}")

print("\n输入 exit、quit 或 退出 可结束程序。\n")

system_message = {
    "role": "system",
    "content": "你是一名专业、严谨、友好的中文人工智能助手。",
}

history = []

while True:
    try:
        question = input("用户:").strip()
    except (KeyboardInterrupt, EOFError):
        print("\n程序结束。")
        break

    if not question:
        continue

    if question.lower() in {"exit", "quit"} or question == "退出":
        print("程序结束。")
        break

    messages = [
        system_message,
        *history,
        {"role": "user", "content": question},
    ]

    prompt = tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=True,
    )

    model_inputs = tokenizer(
        [prompt],
        return_tensors="pt",
    )

    # device_map分片模型通常从第0张卡接收输入。
    model_inputs = {
        key: value.to("cuda:0")
        for key, value in model_inputs.items()
    }

    input_length = model_inputs["input_ids"].shape[1]

    try:
        with torch.inference_mode():
            output_ids = model.generate(
                **model_inputs,
                max_new_tokens=512,
                do_sample=True,
                temperature=0.7,
                top_p=0.9,
                repetition_penalty=1.05,
                pad_token_id=tokenizer.eos_token_id,
            )

        generated_ids = output_ids[0, input_length:]
        answer = tokenizer.decode(
            generated_ids,
            skip_special_tokens=True,
        ).strip()

        print(f"\n助手:{answer}\n")

        history.append({"role": "user", "content": question})
        history.append({"role": "assistant", "content": answer})

        # 最多保留最近6轮对话,避免上下文持续增长。
        history = history[-12:]

    except torch.OutOfMemoryError:
        print("\n显存不足,已清理显存缓存。")
        print("建议缩短输入内容,或把 max_new_tokens 调低至 256。\n")
        torch.cuda.empty_cache()

    except Exception as exc:
        print(f"\n推理失败:{type(exc).__name__}: {exc}\n", file=sys.stderr)

PY

6.启动模型

加载环境变量:

source /root/private_data/llm/env.sh

运行:

python3 /root/private_data/llm/code/chat_qwen32b.py

第一次会经历模型分片读取和双卡分配。

加载完成后,终端会出现:

用户:

输入测试问题:

请用通俗语言解释什么是大语言模型。

退出时输入:

exit

或:

退出

7.监控两张卡是否都在使用

在 Notebook 中再打开一个终端,执行:

watch -n 2 hy-smi

运行模型时,应能看到:

两张卡的显存占用均明显增加;
HCU 利用率在生成文本时上升;
温度和功率随推理负载变化。

退出监控:

Ctrl + C

8.后台运行并保存日志

需要关闭终端后继续运行时,可以使用:

nohup python3 /root/private_data/llm/code/chat_qwen32b.py \
  > /root/private_data/llm/logs/qwen32b.log 2>&1 &

但交互式聊天不适合完全后台运行。后台模式主要用于后续 API 服务。

查看进程:

ps -ef | grep chat_qwen32b.py | grep -v grep

查看日志:

tail -f /root/private_data/llm/logs/qwen32b.log

停止进程:

pkill -f chat_qwen32b.py

9.创建进入Ai的快捷方式

一次性创建快捷命令

mkdir -p /root/private_data/llm/code

cat > /root/private_data/llm/code/start_qwen.sh <<'EOF'
#!/bin/bash

export HIP_VISIBLE_DEVICES=0,1
export TOKENIZERS_PARALLELISM=false

exec python3 /root/private_data/llm/code/chat_qwen32b.py
EOF

cat > /root/private_data/llm/code/ai.sh <<'EOF'
#!/bin/bash

SESSION="qwen"
START_SCRIPT="/root/private_data/llm/code/start_qwen.sh"

if ! command -v tmux >/dev/null 2>&1; then
    echo "错误:没有安装 tmux"
    echo "请执行:apt-get update && apt-get install -y tmux"
    exit 1
fi

if [ ! -f "$START_SCRIPT" ]; then
    echo "错误:启动脚本不存在:$START_SCRIPT"
    exit 1
fi

if tmux has-session -t "$SESSION" 2>/dev/null; then
    echo "正在进入已有 AI 问答会话……"
    exec tmux attach-session -d -t "$SESSION"
else
    echo "正在创建 AI 问答会话并加载模型……"
    exec tmux new-session -s "$SESSION" "$START_SCRIPT"
fi
EOF

chmod +x /root/private_data/llm/code/start_qwen.sh
chmod +x /root/private_data/llm/code/ai.sh

grep -qxF "alias ai='/root/private_data/llm/code/ai.sh'" ~/.bashrc || \
echo "alias ai='/root/private_data/llm/code/ai.sh'" >> ~/.bashrc

source ~/.bashrc

以后进入问答

直接执行:

ai

暂时离开但不关闭模型

在问答界面依次按:

Ctrl + B

松开后按:

D

这样只是离开界面,模型仍在后台运行。再次输入:

ai

可立即回到原来的问答。

完全关闭助手

在问答界面输入:

exit

可供修改

1.输出内容上限修改

先另开一个终端,检查当前设置:

grep -n "max_new_tokens" \
  /root/private_data/llm/code/chat_qwen32b.py

建议先从 512 改成 1024:

sed -i 's/max_new_tokens=512/max_new_tokens=1024/' \
  /root/private_data/llm/code/chat_qwen32b.py

确认:

grep -n "max_new_tokens" \
  /root/private_data/llm/code/chat_qwen32b.py

2.模型修改

你准备改下其他模型,建议删除当前未完成目录:

rm -rf /root/private_data/llm/models/Qwen2.5-32B-Instruct

删除前也可以先看已占空间:

du -sh /root/private_data/llm/models/Qwen2.5-32B-Instruct

然后再下载新模型,例如:

modelscope download \
  --model Qwen/Qwen3-32B \
  --local_dir /root/private_data/llm/models/Qwen3-32B
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐