为保护AI模型资产或处理金融、医疗等敏感数据,可使用阿里云TDX机密计算实例,通过远程证明获取密钥以解密和部署Qwen模型,实现AI推理过程的硬件级数据保护,从而保障核心资产安全。
应用场景
金融/医疗行业的合规AI:在处理包含个人身份信息或受保护健康信息的文本时,利用机密计算确保数据在推理过程中不被泄露,满足合规要求。
企业私有知识库:企业希望使用内部的、敏感的文档(如财务报表、研发资料)来增强大模型,但又不希望这些核心数据在云端以明文形式暴露。本方案可确保知识库数据和微调后的模型都受到硬件保护。
保护商业模型资产:对于AI服务提供商,其精心训练的专有模型是核心商业资产。本方案可以防止模型在云端被非法复制或窃取。
方案概述
Confidential AI方案介绍
Confidential AI是阿里云提供的一种在不被信任的云环境中安全执行AI任务的解决方案。它的核心价值在于,借助Intel TDX等机密计算硬件技术,为AI模型和敏感数据提供一个“硬件保险箱”(即机密环境),实现端到端的安全与隐私保护。
核心组件解释
Trustee:可理解为“密钥保险箱”。主要负责安全地存储和管理用于解密AI模型的密钥。只有经过严格远程证明(Remote Attestation)的可信请求才能从中获取密钥。
Trustiflux:可以将其视为云端的“可信守门员”。部署在TDX实例内部,核心职责是通过远程证明流程,向Trustee证明当前运行环境是真实、未被篡改的TDX机密环境。只有“自证清白”后,Trustiflux才能从Trustee获取密钥。
整体流程概览
您的可信环境中:下载原始AI模型 -> 加密模型 -> 将密钥存入Trustee。
机密计算环境中(TDX实例):
TDX实例中的Trustiflux发起远程证明 -> Trustee验证证明 -> 验证通过后,Trustee将密钥发送给Trustiflux。
Trustiflux获取加密的模型 -> 使用收到的密钥解密模型。
在机密环境中加载解密后的模型,并启动AI推理服务。
准备工作
ECS资源准备:创建一台TDX机密计算实例,关键配置项如下:
地域及可用区:华北2(北京)可用区I。
实例规格:Qwen-7B-Chat模型运行时约需30 GiB内存。为确保稳定,建议选择
ecs.g8i.4xlarge
(16 vCPU, 64 GiB内存) 或更高规格。镜像:选择
Alibaba Cloud Linux 3.2104 LTS 64位
,并勾选机密虚拟机选项。公网IP:务必勾选分配公网IPv4地址,带宽建议选择按使用流量并设置峰值为100 Mbps,以加速模型下载。
数据盘:模型及相关文件会占用较大空间,建议系统盘至少为
100 GiB
。
安全组配置:在安全组中放行以下端口的入站流量。管理安全组规则
22
:用于SSH远程登录。9090
:用于后续步骤中,从云端获取加密模型的临时HTTP服务。7860
:用于访问最终部署的Qwen Web UI或API服务。50005
:(可选)用于TNG保证推理提示词和推理响应结果的信道安全。
步骤一:在可信环境下准备加密模型和密钥
首先需要完成模型下载、加密以及配置Trustee来保管密钥。为方便演示,本文后续实操步骤在同一TDX实例中进行。在实际部署时,请在您的本地或可信环境下运行。
安装基础工具
使用root用户登录实例,安装Trustee、gocryptfs及其他依赖。
yum install -y trustee gocryptfs tmux git git-lfs wget && git lfs install # 启动trustee服务 systemctl start trustee
下载
Qwen-7B-Chat
模型模型文件较大,下载耗时较长(约15-20分钟),建议在
tmux
会话中执行,以防SSH连接断开导致下载中断。# 创建工作目录 mkdir -p /cai/trustee && cd /cai/trustee # 创建并进入一个名为 qwen_clone 的 tmux 会话 # 提示:使用 tmux 可以防止因网络波动或SSH客户端关闭导致下载任务中断。 tmux new-session -d -s qwen_clone "git clone https://www.modelscope.cn/qwen/Qwen-7B-Chat.git qwen-7b-chat --depth=1" # 观察下载进度 # 提示:下载完成后,进程会退出,并显示[exited] tmux attach -t qwen_clone
加密模型文件
使用
gocryptfs
工具创建一个加密目录,并将模型文件移入,自动执行模型加密。# 准备用于存放加密数据(cipher)和解密后挂载点(plain)的目录 mkdir -p /cai/trustee/mount/{cipher,plain} # 创建一个密码文件用于加密。在生产环境中,应使用更安全的随机密码 printf '123456' > /cai/trustee/sample_password # 使用密码文件初始化 gocryptfs 加密目录 cat /cai/trustee/sample_password | gocryptfs -init /cai/trustee/mount/cipher # 以后台进程方式,将加密目录挂载到明文挂载点 (cat /cai/trustee/sample_password | gocryptfs /cai/trustee/mount/cipher /cai/trustee/mount/plain &) && sleep 2 # 将模型文件移动到明文挂载点。gocryptfs会自动处理加密过程,将加密后的数据写入cipher目录。由于文件较大,加密过程需等待5分钟左右。 mv /cai/trustee/qwen-7b-chat/ /cai/trustee/mount/plain # 操作完成,卸载明文挂载点 fusermount -u /cai/trustee/mount/plain
预期结果
执行完毕后,运行
ls /cai/trustee/mount/cipher
,应该看到若干加密后的文件名,而不是qwen-7b-chat
。同时,运行ls /cai/trustee
,确认qwen-7b-chat
目录已不存在。
保存密钥至Trustee
将上一步中用到的密码文件,安全地存放到
Trustee
的密钥库中。mkdir -p /opt/trustee/kbs/repository/cai/sample/ mv /cai/trustee/sample_password /opt/trustee/kbs/repository/cai/sample/password
启动本地HTTP服务
启动一个临时的Web服务器,用于向云端环境提供加密后的模型文件。
# 此命令会启动一个监听在127.0.0.1:9090的服务,保持此终端窗口运行 cd /cai/trustee/mount/cipher && python3 -m http.server 9090 --bind 127.0.0.1
步骤二:在云端机密环境中解密并挂载模型
请在第二个SSH终端窗口中进行本章操作。
在执行操作前,请确保步骤一中通过
python3 -m http.server
命令启动的服务仍在第一个终端中运行。否则,本章的wget
命令将无法找到下载源而失败。
安装Trustiflux
在第二个终端中,安装attestation-agent(证明代理)和confidential-data-hub(机密数据中心)及相关环境依赖。
yum install -y attestation-agent confidential-data-hub gocryptfs wget
执行远程证明并获取密钥
以下命令将配置并启动证明服务,与本地的Trustee(在本例中为同一台机器的127.0.0.1)通信,验证成功后获取模型密钥并保存。
密钥传输安全由 Trustiflux 和 Trustee 之间基于 TEE 的应用层加密协议(KBS Attestation Protocol)提供保障。
# 配置attestation-agent和confidential-data-hub以与本地Trustee通信 sed -i "/^\[token_configs\.kbs\]$/,/^$/ s|^url = .*|url = \"http://127.0.0.1:8080\"|" \ /etc/trustiflux/attestation-agent.toml sed -i "/^\[token_configs\.coco_as\]$/,/^$/ s|^url = .*|url = \"http://127.0.0.1:50004\"|" \ /etc/trustiflux/attestation-agent.toml sed -i 's|\(url\s*=\s*"\)[^"]*|\1http://127.0.0.1:8080|' \ /etc/trustiflux/confidential-data-hub.toml # 启动证明代理,然后请求密钥资源 attestation-agent -c /etc/trustiflux/attestation-agent.toml > /dev/null 2>&1 & PID=$! && sleep 1 password=$(confidential-data-hub \ -c /etc/trustiflux/confidential-data-hub.toml \ get-resource \ --resource-uri kbs:///cai/sample/password) mkdir -p /cai/trustiflux && echo "$password" | base64 -d > "/cai/trustiflux/sample_password"
预期结果
命令成功执行后,可在
/cai/trustiflux/sample_password
路径下找到内容为123456
的密码文件。若没有该文件,需检查步骤一中本地HTTP服务是否处于运行中。未处于运行中需重新启动服务并保持终端窗口运行。
获取并解密模型
# 使用wget递归下载在步骤 1.5 中公开的加密模型文件 wget -c --tries=30 --timeout=30 --waitretry=15 \ -r -np -nH --cut-dirs=0 -R "index.html*" \ --progress=dot:giga --show-progress \ -P /cai/trustiflux/mount/cipher \ http://127.0.0.1:9090 # 创建明文挂载点 mkdir -p /cai/trustiflux/mount/plain # 使用之前通过远程证明获取的密钥,将下载的加密模型目录挂载到明文挂载点 gocryptfs -debug -passfile /cai/trustiflux/sample_password /cai/trustiflux/mount/cipher /cai/trustiflux/mount/plain
预期结果
命令执行后,终端将输出
Filesystem mounted and ready
。执行ls /cai/trustiflux/mount/plain
,可以看到解密后的qwen-7b-chat
目录。若
wget
下载加密模型时连接被拒绝 (Connection refused),需检查步骤一中本地HTTP服务是否处于运行中。未处于运行中需重新启动服务并保持终端窗口运行。
步骤三:启动并访问Qwen推理服务
请在第三个SSH终端中执行本章操作。
准备Python环境与依赖
在第三个终端中,使用Conda创建并激活一个新的Python环境。
# 下载并安装Miniconda wget https://repo.anaconda.com/miniconda/Miniconda3-py39_23.11.0-2-Linux-x86_64.sh bash Miniconda3-py39_23.11.0-2-Linux-x86_64.sh -b -p $HOME/miniconda # 激活Conda环境 source $HOME/miniconda/bin/activate # 创建并激活专用的Python 3.10环境 conda create -n pytorch_env python=3.10 -y conda activate pytorch_env
预期结果
终端提示符前出现
(pytorch_env)
。
选择一种方式启动服务(三选一)
通过API编程方式调用模型:选择启动OpenAI兼容的API服务。
通过图形化界面与模型交互:选择启动Web UI服务。
直接在服务器终端与模型对话:选择启动命令行交互式对话。
启动OpenAI兼容的API服务
# 激活专用的Python 3.10环境 source $HOME/miniconda/bin/activate conda activate pytorch_env cd /cai/trustiflux git clone https://github.com/QwenLM/Qwen.git cd Qwen pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu pip3 install -r requirements.txt && pip3 install fastapi uvicorn "openai<1.0" pydantic sse_starlette python openai_api.py -c ../mount/plain/qwen-7b-chat --cpu-only --server-name 0.0.0.0 --server-port 7860
访问方式:在任何可以访问ECS公网IP的终端上,使用
curl
命令调用:本文以本地终端为例。
curl -X POST http://<TDX实例公网IP地址>:7860/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "Who are you?" } ] }'
输出如图所示:
启动Web UI服务
# 激活专用的Python 3.10环境 source $HOME/miniconda/bin/activate conda activate pytorch_env cd /cai/trustiflux git clone https://github.com/QwenLM/Qwen.git cd Qwen pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu pip3 install -r requirements.txt && pip3 install -r requirements_web_demo.txt python3 web_demo.py -c ../mount/plain/qwen-7b-chat --cpu-only --server-name 0.0.0.0 --server-port 7860
访问方式:在您的本地浏览器地址栏输入
http://<ECS公网IP地址>:7860
。启动命令行交互式对话
# 激活专用的Python 3.10环境 source $HOME/miniconda/bin/activate conda activate pytorch_env cd /cai/trustiflux git clone https://github.com/QwenLM/Qwen.git cd Qwen pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu pip3 install -r requirements.txt python3 cli_demo.py -c ../mount/plain/qwen-7b-chat --cpu-only
访问方式:启动后,直接在终端的
User>
提示符后输入问题即可。如图所示:
步骤四:(可选)通过TNG增强信道安全
为了实现从客户端到云端机密环境的全链路加密,可使用可信网络网关(TNG)来保护通信信道,防止推理提示词和推理响应结果在传输过程中被窃听。
以通过API与模型对话为例,执行操作前,请确保步骤三中的OpenAI兼容的API服务已启动。
服务端(TDX实例)部署TNG
在TDX实例上打开第四个终端,执行以下命令:
yum install -y trusted-network-gateway tng launch --config-content '{ "add_egress": [{ "netfilter": { "capture_dst": { "port": 7860 }, "capture_local_traffic": true, "listen_port": 40001 }, "attest": { "aa_addr": "unix:///run/confidential-containers/attestation-agent/attestation-agent.sock" } }] }'
客户端(本地机器)部署TNG
在您的本地机器上下载并运行TNG。
TNG更多版本
本地为x86_64
# x86_64 wget https://github.com/inclavare-containers/TNG/releases/download/v2.2.4/tng-v2.2.4.x86_64-unknown-linux-gnu.tar.gz tar -zxvf tng-v2.2.4.x86_64-unknown-linux-gnu.tar.gz && chmod +x tng ./tng launch --config-content '{ "add_ingress": [{ "http_proxy": { "proxy_listen": { "host": "127.0.0.1", "port": 41000 } }, "verify": { "as_addr": "http://<TDX实例公网IP地址>:50005", "policy_ids": [ "default" ] } }] }'
本地为aarch64
# aarch64 wget https://github.com/inclavare-containers/TNG/releases/download/v2.2.4/tng-v2.2.4.aarch64-unknown-linux-gnu.tar.gz tar -zxvf tng-v2.2.4.aarch64-unknown-linux-gnu.tar.gz && chmod +x tng ./tng launch --config-content '{ "add_ingress": [{ "http_proxy": { "proxy_listen": { "host": "127.0.0.1", "port": 41000 } }, "verify": { "as_addr": "http://<TDX实例公网IP地址>:50005", "policy_ids": [ "default" ] } }] }'
通过TNG代理访问服务
打开新的本地命令行,执行以下命令,配置HTTP代理后,通过加密信道与模型对话:
# 临时设置环境变量,配置HTTP代理 export http_proxy=http://127.0.0.1:41000 # 通过API与模型对话 curl -X POST http://<TDX实例公网IP地址>:7860/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "Who are you?" } ] }'
常见问题(FAQ)
安装trustee时报错"Error: Transaction test error"
原因:系统中已安装的SGX/TDX依赖与trustee冲突。
解决:
yum remove libsgx-dcap-default-qpl libsgx-dcap-quote-verify
后再重新安装。
wget
下载加密模型时连接被拒绝 (Connection refused)原因:步骤一中第5步启动的
python3 -m http.server
服务已停止。解决:返回到执行该命令的终端(第一个终端),确保服务仍在运行。如果已停止,请重新进入
/cai/trustee/mount/cipher
目录并再次启动它。
浏览器无法访问Web UI(
http://<ECS公网IP地址>:7860
)原因与排查:
安全组规则:检查安全组是否已为公网放行TCP 7860端口。
服务监听地址:确保启动命令中包含了
--server-name 0.0.0.0
。服务运行状态:在第三个终端检查
web_demo.py
进程是否仍在正常运行。
获取密钥文件时报错:
{code: 111, kind: ConnectionRefused, message: "Connection refused"}
原因:通过
systemctl status trustee
命令检查实例的trustee服务是否处于运行中。若为inactive
,代表未运行。解决:执行
systemctl start trustee
命令启动trustee服务。