TensorFusion Docs

在宿主机/虚拟机安装

在宿主机(Host)运行 tensor-fusion-worker,在虚拟机(VM)内部署 tensor-fusion-client,实现无需直通 GPU 的虚拟机使用物理机 GPU 资源,此模式即 TensorFusion Engine。

架构概览

TensorFusion Engine 在 VM/宿主机形态下由 Client 侧 vGPU 运行时Host 侧 Worker 两部分组成。与传统"调用劫持 + 直接转发"的远程 GPU 方案不同,TensorFusion Engine 在 Client 内部构建了一个 本地 vGPU(Local vGPU Runtime):业务进程发起的每一次 CUDA/NVML 调用,都会先进入 Client 内的 vGPU 语义层完成本地上下文建模、显存视图维护、请求合并与 QoS 判定,再以合适的时机、批次发往宿主机上的 Worker。

TensorFusion Engine VM 部署架构:Client 侧本地 vGPU 运行时与 Host 侧 Worker

这一设计带来了几个关键收益:

  • 降低跨 VM/网络通信开销:本地 vGPU 会过滤掉大量无需落到物理 GPU 的 CUDA 元数据查询(例如 cuCtxGetCurrentcuDeviceGetAttribute 等),只将真正需要硬件执行的请求发往 Worker。
  • 保持语义完整性:vGPU 在 Client 侧重建了完整的 CUDA 上下文、流 (Stream)、事件 (Event) 及显存指针映射,业务进程感知到的行为与本地物理 GPU 一致。
  • 更优的调度时机:vGPU 可以在发送之前进行请求合并与批处理,避免远端 Worker 被小粒度调用反复打断。

名词解释

为便于理解后续部署步骤,这里按模块给出相关术语的精确定义。

宿主机侧 (Host)

  • tensor-fusion-worker(简称 Worker):运行在 GPU 宿主机上的独立二进制,是真实持有 NVIDIA 物理 GPU 驱动的一端。每台宿主机可并行运行多个 Worker 实例,负责接收来自一个或多个 Client 的请求、执行资源仲裁与配额限制,并调用本地 CUDA/NVML 完成计算。
  • ResourceLimiter:Worker 内置的显存与算力配额执行器,用于在多 Client 场景下对 TFLOPs 与 VRAM 进行隔离,防止互相抢占。
  • Physical GPU:宿主机上实际的 NVIDIA GPU 硬件设备。每个 Worker 实例绑定一张 Physical GPU;若宿主机上有多张 GPU,通常并行运行多个 Worker 实例(每个 Worker 绑定一张 GPU)。Client 侧完全无需直通该设备。

业务侧 (Guest / VM)

  • tensor-fusion-client(简称 Client):部署在业务 VM 或容器内的一组动态链接库,完整导出 CUDA 与 NVML API,对业务进程而言与系统自带的 libcuda.so / nvcuda.dll 行为一致。
  • 本地 vGPU(Local vGPU Runtime):Client 内部的核心组件,本质上是一个运行在业务进程地址空间内的轻量级虚拟 GPU。它不是对 CUDA 调用的简单代理,而是会在本地重建 CUDA 上下文、维护虚拟显存视图、合并和重排请求,随后按 QoS 与时机策略决定将请求投递到哪个 Worker。
  • vGPU 上下文 (vContext):本地 vGPU 为每个 CUDA Context / Stream 维护的影子状态,用于保持跨调用的语义一致性。
  • 业务进程:真正使用 GPU 的上层应用,例如 PyTorch、vLLM、TensorRT、Triton Inference Server 等。

通信层 (Transport)

Client 与 Worker 之间可在三种底层传输上协商连接,按部署拓扑选择最合适的一种:

  • TCP (NATIVE):基于 TCP/IP 的网络通信,通过 IP + 端口连接,部署简单、兼容性最好,适合内网低延迟场景(建议 RTT 低于 0.8ms)。
  • RDMA:基于 InfiniBand / RoCE 的远程直接内存访问,零拷贝、低 CPU 开销,适合跨节点高吞吐、低抖动的推理与训练场景。
  • 共享内存 (SHMEM):基于 IVSHMEM 共享内存通道,仅用于 VM 与同宿主机 Host 之间通信,拥有接近本地调用的延迟,适合对时延最敏感的推理场景。
  • IVSHMEM (Inter-VM Shared Memory):QEMU/KVM 提供的虚拟设备,允许 VM 与宿主机通过一块物理共享内存互通,是共享内存连接的底层载体。
  • TENSOR_FUSION_OPERATOR_CONNECTION_INFO:Client 端用于描述"如何连上 Worker"的连接串,格式为 <协议>+<参数1>+<参数2>+<连接版本号>(版本号目前固定为 0)。

注意:多个 Client 可以连接到同一个 Worker 实例,但在生产环境中建议每个 Client 对应一个独立的 Worker 实例,以便于资源配额、故障隔离与可观测性管理。

前提条件

  1. 一台拥有 NVIDIA GPU 的 Linux 宿主机,建议 GPU 驱动版本 570.XX 及以上
  2. 一台或多台虚拟机(QEMU / MVisor / VMware / Hyper-V 等均可),与宿主机能够通过网络或共享内存进行互通

步骤一:下载 tensor-fusion

分别下载 Worker 和 Client 相关文件:

# 下载 tensor-fusion-worker
wget https://cdn.tensor-fusion.ai/archive/remote-gpu-worker/nvidia/v2.12.0/linux-amd64/tensor-fusion-worker
chmod +x tensor-fusion-worker

# 下载 tensor-fusion-client
mkdir -p tensor-fusion-client/linux
wget -O tensor-fusion-client/linux/libcuda.so https://cdn.tensor-fusion.ai/archive/remote-gpu-client/nvidia/v2.12.0/linux-amd64/libcuda.so
wget -O tensor-fusion-client/linux/libnvidia-ml.so https://cdn.tensor-fusion.ai/archive/remote-gpu-client/nvidia/v2.12.0/linux-amd64/libnvidia-ml.so
wget -O tensor-fusion-client/linux/libteleport.so https://cdn.tensor-fusion.ai/archive/remote-gpu-client/nvidia/v2.12.0/linux-amd64/libteleport.so

以上为 Linux 版本下载地址。Windows 版本构建包请联系 support@tensor-fusion.com 获取。

步骤二:在宿主机安装 tensor-fusion-worker

在宿主机上执行步骤一的下载命令得到 tensor-fusion-worker 二进制,先用 -h 查看可用参数:

./tensor-fusion-worker -h
Usage: tensor-fusion-worker [option]
Options
  -h, --help            Display this information.
  -v, --version         Display version information.
  -n, --net             Specified network protocol.
  -p, --port            Specified the port for server.
  -l, --load            Specified the file path of snapshot.
  -m, --shmem-file      Specified the file path of shared memory.
  -M, --shmem-size      Specified the size(MB) of shared memory.

注意

  1. 目前 Worker 支持三种连接方式:NATIVE(TCP)RDMASHMEM(共享内存)
  2. NATIVE:直接通过 TCP 网络通信,部署简单,建议在内网且 ping 值保持在 0.8ms 以内时使用
  3. RDMA:基于 InfiniBand / RoCE 的零拷贝网络,带宽高、CPU 占用低,适合跨节点高吞吐场景(需具备 IB/RoCE 网卡及驱动)
  4. SHMEM:通过共享内存进行通信,效率最高,适合同宿主机 VM 与 Host 之间对时延最敏感的场景
  5. -l, --load 用于 Worker 热升级时从快照文件恢复内存与上下文,常规首次部署无需设置

设置 License

Worker 启动时必须通过环境变量提供 License 内容与签名,否则会拒绝启动:

export TF_LICENSE="<license 内容>"
export TF_LICENSE_SIGN="<license 签名>"

如需获取 License,请联系 support@tensor-fusion.com

启动 Worker

使用 NATIVE 协议启动,绑定端口号 12345:

TF_ENABLE_LOG=1 ./tensor-fusion-worker -n native -p 12345

使用 SHMEM 协议启动,创建共享内存 /my_shm,设置大小 256 MB:

TF_ENABLE_LOG=1 ./tensor-fusion-worker -n shmem -m /my_shm -M 256

RDMA 协议启动命令需根据具体 IB / RoCE 网卡和驱动配置确定,请联系 support@tensor-fusion.com 获取对应参数。

完整环境变量列表:

  • TF_ENABLE_LOG: 启用日志记录,默认为禁用
  • TF_LOG_LEVEL: 日志级别,支持值为 trace / debug / info / warn / error,默认为 info
  • TF_LOG_PATH: 日志文件路径,默认为空(即输出到标准输出)
  • TF_GPU_MEMORY_LIMIT: GPU 内存限制,单位 MB,默认不限制
  • TF_LICENSE: 授权许可证内容,启动时必须设置
  • TF_LICENSE_SIGN: 授权许可证签名,与 TF_LICENSE 配对使用,启动时必须设置

步骤三:在 VM 中安装 tensor-fusion-client

将步骤一下载得到的 tensor-fusion-client 目录复制到业务 VM 内,根据操作系统选择注入方式:

Linux 系统

tensor-fusion-client/linux 目录下的 libcuda.solibnvidia-ml.solibteleport.so 通过 LD_LIBRARY_PATHLD_PRELOAD 注入业务进程。

  • 若业务进程已通过系统路径链接到真实 libcuda.so,使用 LD_PRELOAD 强制抢先加载(推荐)
  • 若系统中不存在 libcuda.soLD_LIBRARY_PATH 亦可生效

Windows 系统

tensor-fusion-client/windows 目录下的 nvcuda.dllnvml.dllteleport.dll 放置在系统 PATH 中,或与业务程序放在同一目录下。

Windows 版本构建包不在步骤一的默认下载列表中,请联系 support@tensor-fusion.com 获取。

注意:由于用户操作系统环境复杂,请通过 ldd(Linux)或 Process Explorer(Windows)确认 Client 的动态链接库已被业务进程成功加载并使用。

Client 端环境变量:

  • TF_ENABLE_LOG: 启用日志记录,默认为禁用
  • TF_LOG_LEVEL: 日志级别,支持值为 trace / debug / info / warn / error,默认为 info
  • TF_LOG_PATH: 日志文件路径,默认为空(Linux 下输出到控制台,Windows 下可通过 DebugView 查看)
  • TENSOR_FUSION_OPERATOR_CONNECTION_INFO: Worker 连接参数,格式为 <协议>+<参数1>+<参数2>+<连接版本号>(版本号目前固定为 0),默认为空
  • TENSOR_FUSION_OPERATOR_GET_CONNECTION_URL: 用于动态获取连接参数的 HTTP(S) 地址;Client 启动时会向该地址发起 GET 请求并以返回值作为连接串,默认为空
  • TF_MAX_CACHE_REQUEST_COUNT: 最大缓存请求数量,默认为 100

注意:TENSOR_FUSION_OPERATOR_CONNECTION_INFOTENSOR_FUSION_OPERATOR_GET_CONNECTION_URL 二选一即可。两者同时设置时以 CONNECTION_INFO 为准;Kubernetes / Operator 自动下发连接信息的场景推荐使用 GET_CONNECTION_URL

步骤四:验证

在 Linux VM 内使用 Python + PyTorch (CUDA) 进行端到端验证。

基础环境变量

打开日志并将 Client 动态库注入业务进程:

export TF_ENABLE_LOG=1
export LD_PRELOAD=/opt/tensor-fusion-client/linux/libteleport.so:/opt/tensor-fusion-client/linux/libcuda.so:/opt/tensor-fusion-client/linux/libnvidia-ml.so

以上假设 tensor-fusion-client 路径为 /opt/tensor-fusion-client,请根据实际情况调整。

连接信息配置

根据 Worker 启动时使用的协议,选择对应的连接串。

方式一:NATIVE (TCP)

若 Worker 以 NATIVE 协议启动(宿主机 IP 为 192.168.1.100,端口 12345),连接串格式: native+<宿主机IP>+<端口>+<连接版本号>

export TENSOR_FUSION_OPERATOR_CONNECTION_INFO=native+192.168.1.100+12345+0

请确保 VM 能够访问宿主机的 IP 和端口(防火墙 / 安全组放通)。

方式二:SHMEM (共享内存)

若 Worker 以 SHMEM 协议启动(共享内存 /my_shm,大小 256 MB),需先通过 QEMU 把共享内存作为 IVSHMEM 设备透传给 VM:

qemu-system-x86_64 \
   -m 8192 \
   -hda centos8.4.qcow2 \
   -vnc :1 \
   -enable-kvm \
   -cpu host \
   -object memory-backend-file,id=shm0,mem-path=/dev/shm/my_shm,size=256M,share=on \
   -device ivshmem-plain,memdev=shm0 \
   -smp 4

1. 在 VM 中查找 IVSHMEM 设备的 PCI 地址:

lspci -vv | grep -i Inter-VM

可能的输出:

00:04.0 RAM memory: Red Hat, Inc. Inter-VM shared memory (rev 01)

可以得出 IVSHMEM 设备的 PCI 地址为 00:04.0,对应的 sysfs resource 文件路径为 /sys/devices/pci0000:00/0000:<PCI地址>/resource2,本例即 /sys/devices/pci0000:00/0000:00:04.0/resource2

2. 设置 Worker 连接信息,格式:shmem+<IVSHMEM resource 文件路径>+<共享内存大小(MB)>+<连接版本号>

export TENSOR_FUSION_OPERATOR_CONNECTION_INFO=shmem+/sys/devices/pci0000:00/0000:00:04.0/resource2+256+0

注意

  1. 连接串中的共享内存大小必须与 Worker 启动时的 -M 值保持一致
  2. 映射 IVSHMEM resource 文件需要 root 权限

PyTorch 验证示例

完成上述环境变量设置后,运行以下脚本(PyTorch + Qwen3 0.6B)进行验证:

# 使用中科大镜像(仅此次命令生效,不修改全局 pip 配置)
pip install -i https://pypi.mirrors.ustc.edu.cn/simple \
    torch modelscope packaging transformers accelerate

cat << 'EOF' > test-qwen.py
from modelscope import AutoModelForCausalLM, AutoTokenizer

model_name = "Qwen/Qwen3-0.6B"

tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="cuda:0"
)

prompt = "Give me a short introduction to large language model."
messages = [
    {"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True,
    enable_thinking=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
generated_ids = model.generate(
    **model_inputs,
    max_new_tokens=32768
)
output_ids = generated_ids[0][len(model_inputs.input_ids[0]):].tolist()
try:
    # rindex finding 151668 (</think>)
    index = len(output_ids) - output_ids[::-1].index(151668)
except ValueError:
    index = 0

thinking_content = tokenizer.decode(output_ids[:index], skip_special_tokens=True).strip("\n")
content = tokenizer.decode(output_ids[index:], skip_special_tokens=True).strip("\n")

print("thinking content:", thinking_content)
print("content:", content)
EOF

python3 test-qwen.py

验证通过的判据:

  • 在 VM 内看到模型正常生成输出(content: 后有中文或英文文本)
  • 宿主机上运行 nvidia-smi 可以看到 tensor-fusion-worker 进程及其 GPU 显存占用(VM 内执行 nvidia-smi 不会看到真实 GPU,因为业务 VM 并未直通物理设备)

目录