StreamTurbo 安裝與使用:在 TouchDesigner 做即時 AI 影像,4 GB 顯示卡也能跑

摘要

StreamTurbo 是從 StreamDiffusion 獨立改寫的 TouchDesigner 即時影像生成工具,雙擊 start.cmd 就會裝好 Python、CUDA 套件與模型。它用 sd-turbo 單步生成 512×512,再由內建的 Upscaler 放大到 2048×2048。本文附上 RTX 3070 在 60% 功率上限下的實測數據,以及 4 GB 筆電顯示卡的執行結果。

文章目錄

StreamTurbo 是我給 TouchDesigner(以下簡稱 TD)用的即時 AI 影像工具。TD 送出畫面,它用 Stability AI 的單步生成模型 sd-turbo 重新畫過每一格,再送回 TD。安裝只要下載專案後雙擊 start.cmd,Python、CUDA 套件、模型和 TensorRT 加速都會自動準備好,不必自己對版本。生成的 512×512 畫面可以交給內建的放大模型 Upscaler 放大到 2048×2048,在 RTX 3070 上每秒約 21 格(fps)。4 GB VRAM 的筆電顯示卡也跑得動,設定與輸出解析度都不用改,只是速度降到約 6 fps。

StreamTurbo 是從 StreamDiffusion 獨立出來重寫的專案。照 StreamDiffusion 的安裝教學常會卡在 Python、CUDA 或 huggingface_hub 的版本衝突,例如 ImportError: cannot import name 'cached_download' from 'huggingface_hub',這是 diffusers 和新版 huggingface_hub 不相容造成的。StreamTurbo 用 lockfile(記錄每個套件確切版本的檔案)固定所有套件的版本,可以避開這類問題。本文以 1.0.0 為準。

和 StreamDiffusion 有什麼不同

StreamDiffusion 是為多步生成設計的,一張圖要反覆計算好幾次,它的 Stream Batch、Residual CFG 等加速手段也都建立在多步的前提上。sd-turbo 只要算一步就能出圖,所以 StreamTurbo 拿掉這些功能,改成一條只為單步生成設計的流程,也不再和原專案相容。

項目 StreamTurbo 1.0 StreamDiffusion
安裝 start.cmd 自動安裝固定版本的套件 手動安裝 Python、CUDA、PyTorch
模型 只有 sd-turbo,每格一步 多種模型,可多步生成
放大 內建 Upscaler,2 倍或 4 倍 未內建
與 TD 連接 NDI 或 Spout,附範例元件 未附 TD 元件

處理影格的方式也不一樣。StreamTurbo 把接收、生成和送出分成三條同時進行的工作,彼此只交接最新的一格。生成跟不上時就丟掉舊的影格,所以延遲不會越積越長。

TouchDesigner 經 NDI 或 Spout 把畫面送進 StreamTurbo,經過接收、sd-turbo 單步生成、Upscaler 放大與送出,再回到 TouchDesigner

需求與安裝

項目 需求
作業系統 Windows 10/11 x64
顯示卡 NVIDIA RTX 20 系列以上,VRAM 4 GB 以上,建議 8 GB
驅動程式 580 以上
其他 git

Mac、AMD 顯示卡、Linux 與 WSL 都不支援。不需要另外安裝 Python、CUDA Toolkit、Visual Studio 或 NDI Tools。打開命令提示字元,用 git 下載 1.0.0 版再執行 start.cmd,之後在檔案總管直接雙擊 start.cmd 也可以:

1git clone --branch v1.0.0 https://github.com/tedliou/StreamTurbo.git
2cd StreamTurbo
3start.cmd

start.cmd 會先檢查驅動程式版本,再把固定版本的 uv(Python 套件管理工具)裝進專案的 cache\bin,依 lockfile 同步 Python 3.12 與所有套件。第一次執行會下載數 GB 的套件,啟動後再下載約 2.3 GB 的模型權重。所有下載都放在專案資料夾裡,之後刪掉整個資料夾就能完整移除。

接著 start.cmd 會執行 streamturbo doctor 檢查環境,通過後就開始生成,並在瀏覽器打開 Web Panel(http://127.0.0.1:8765/)。下面是這台 RTX 3070 在 Engine 建好之後的 doctor 輸出,最後一行是 OK。第一次執行時 Engine 還沒建,Engines 那行不會是 all 4 built,這是正常的:

1GPU
2  [0] NVIDIA GeForce RTX 3070
3      VRAM          8.0 GB
4      power limit   162 W enforced of 270 W default (60%)
5Libraries
6  torch             2.14.1+cu130
7  TensorRT          10.16.1.11
8  Engines           all 4 built in E:\StreamTurbo\engines
9Transports
10  NDI               available
11  Spout             available: SpoutGL 0.1.1
12
13OK

TensorRT 是 NVIDIA 的推論加速工具,它會針對每一張顯示卡分別編譯模型,編譯結果叫做 Engine。Engine 只能在當初編譯它的那張顯示卡上使用,換一張顯示卡就要重新編譯,所以 StreamTurbo 不隨專案附上 Engine,而是第一次啟動時在你的顯示卡上背景建置,RTX 3070 約需 4 分鐘。建好之前先用沒有加速的 PyTorch 輸出,速度大約只有一半。Web Panel(下一節會介紹)上方的 Backend 欄會顯示建置進度,變成 tensorrt 就代表加速已經生效。想在使用前先建好,可以執行 .venv\Scripts\streamturbo build-engines。

之後要更新版本時,在專案資料夾執行 git fetch --tags 和 git checkout v1.x.x(換成新版本的 tag),再執行一次 start.cmd。自己存的 Preset(一組存起來的外觀設定)、上次的設定 last-settings.toml、模型與 Engine 都不在 git 裡,更新時會保留。

接上 TouchDesigner

StreamTurbo 和 TD 之間用 NDI 或 Spout 傳畫面。兩者都是在程式之間傳即時影像的協定:Spout 只能在同一台電腦內,畫面不壓縮。NDI 走網路,可以跨電腦。StreamTurbo 第一次執行時預設用 NDI 收送畫面。

最簡單的方式是使用專案附的範例元件。把 touchdesigner/StreamTurbo.tox 拖進 TD 專案,把要轉換的畫面接到元件的輸入,元件的輸出就是 StreamTurbo 送回來的畫面。元件沒有輸入時會送出一段動態測試畫面,可以先用它確認連線。元件的 Status 頁或 Web Panel 的來源狀態從 waiting 變成 live、每秒格數有數字,就代表接上了。

選取範例元件,參數面板的 StreamTurbo 頁可以直接調整常用的設定,改動會經 OSC(在程式之間傳控制訊息的協定)送給同一台電腦上的 StreamTurbo:

參數 作用
Transport 切換 NDI 或 Spout,同時改 TD 的送出、接收與 StreamTurbo 的來源和輸出
Prompt 提示詞
Strength 越接近 0 越保留輸入畫面,越接近 1 越照提示詞重畫,預設 0.68
Seed 決定隨機花紋的數字,換一個數字就換一種畫法
Temporal Coherence 讓每格參考上一格的特徵,減少細節亂跳
Preset 套用或儲存一組外觀設定,包含提示詞、Strength 等

Status 頁會顯示來源狀態、每秒格數和生成時間。按 Measure Latency 會讓元件在黑畫面和白畫面之間切換,計時到回傳畫面的亮度跟著改變,量出目前設定下從送出到收回的 Round-trip 延遲。

熟悉 OSC 的話,範例元件涵蓋不到的設定,也可以從 TD 的 OSC Out 直接送到 StreamTurbo 的 7000 埠,位址就是設定的路徑,例如 /streamturbo/strength、/streamturbo/prompt_transition。用 LFO 這類會連續變化的訊號送 Strength 時,畫面會依 strength_glide 的秒數平滑跟上,不會一格一格跳。想讓 AI 幫忙在 TD 裡接線,可以參考用 td-cli 讓 AI 操作 TouchDesigner 專案。

用 Web Panel 調提示詞與解析度

Web Panel 是 StreamTurbo 啟動時自動在瀏覽器打開的控制頁面,網址是 http://127.0.0.1:8765/。範例元件只放了常用的幾個參數,完整的設定都在這裡。下圖是範例元件送出測試畫面、StreamTurbo 正在生成時的 Web Panel:

StreamTurbo Web Panel 上方,狀態列顯示 Source Live、18.0 fps、生成時間 54 ms、VRAM 5.2/8.0 GiB 與 tensorrt,左邊是輸入與輸出預覽,右邊是 Prompt Blend 提示詞欄位

最上面一排是狀態列:Source 是來源狀態,Throughput 是每秒格數,Generation Time 是每格處理時間,Backend 顯示目前用 TensorRT 加速還是 PyTorch。左邊的 Previews 可以同時看輸入與輸出的縮圖,不必切回 TD。

提示詞在右邊的 Prompt Blend。改完按 Ctrl+Enter 或點到欄位外面就會套用,畫面依 Prompt Transition 的秒數漸變過去。Add Prompt 可以再加一個提示詞,各自用 Weight 調比重。每個設定右上角的標籤代表套用方式:Live 下一格就生效,輸出不中斷。Reset 會重新配置緩衝區,輸出會停頓一下。

往下捲是生成解析度與輸出解析度兩組設定:

Web Panel 的 Generation Resolution 設為 512×512,Fit Mode 為 Fill,Output Resolution 設為 2048×2048,Upscaler 開啟

  • Generation Resolution(生成解析度)是 sd-turbo 實際作畫的大小,決定每格處理時間和 VRAM 用量。TD 送來的畫面會先縮放到這個大小,比例不同時依 Fit Mode 處理:Fill 裁切填滿,Fit 加黑邊,Stretch 直接拉伸。sd-turbo 在 512×512 的效果最好。
  • Output Resolution(輸出解析度)是送回 TD 的畫面大小,不影響 sd-turbo 怎麼畫,只決定最後放大到多大。輸出大於生成時,開著 Upscaler 就用 AI 模型放大並補細節,關掉就是一般縮放。介面上的說明建議設成生成解析度的 2 倍或 4 倍。

例如 TD 送 1920×1080 的畫面進來,生成 512×512、輸出 2048×2048、Fit Mode 是 Fill,StreamTurbo 會先把畫面裁成正方形再縮到 512×512 生成,最後用 Upscaler 放大成 2048×2048 送回 TD。要更大的輸出時調高輸出解析度,生成解析度維持 512×512。兩組解析度都屬於 Reset,改動時輸出會停頓一下。

Web Panel、範例元件和 OSC 改的是同一份設定,結束時會存進專案資料夾的 last-settings.toml,下次啟動沿用。也可以把設定寫成文字檔,用 start.cmd --settings 檔名.toml 啟動。預設的生成解析度是 1024×768,下面這份設定檔改成本文使用的 512×512 生成、放大到 2048×2048,沒寫到的設定維持預設值:

1temporal_coherence = true
2upscaler = true
3
4[generation]
5width = 512
6height = 512
7
8[output]
9width = 2048
10height = 2048

[generation] 是生成解析度,[output] 是送回 TD 的解析度。upscaler、temporal_coherence 這類單行設定要寫在 [generation] 這些區段之前,否則會被當成區段裡的設定。完整欄位見 README 的設定檔範例。

調出穩定的畫面

即時生成最常遇到的問題是閃爍。sd-turbo 每一格都獨立生成,輸入稍微變動,花紋就會整片重新長一次。StreamTurbo 有兩個互相獨立的設定處理這件事:

  • Temporal Coherence 讓模型生成時參考上一格的內部特徵,原本就有的細節傾向留在原位,畫面不會變糊,預設開啟。
  • Temporal Smoothing 把上一格的畫面混進這一格,數值越高越穩,但快速移動時會拖影,預設 0.2。

畫面還是閃的話,先確認 Temporal Coherence 有開,再把 Temporal Smoothing 從 0.2 往上調,或降低 Strength。提示詞可以用 Prompt Blend 一次放多個並設定權重,換提示詞時會依 prompt_transition 的秒數漸變過去。畫面靜止的場景可以開 Similar Frame Skip,輸入幾乎沒變時就重送上一格,不重新生成。

用 Upscaler 放大 512×512 的輸出

sd-turbo 是在 512×512 上訓練的模型,直接生成更大的畫面,構圖容易重複或崩壞,比較穩的做法是生成 512×512 再放大。問題是螢幕或投影機常常要 1920 以上,一般縮放只是把像素拉大,放大後的邊緣會糊成一片。

StreamTurbo 的 Upscaler 是一個小型的超解析度模型,架構來自 Real-ESRGAN 的 SRVGGNetCompact,在專案裡重新實作,也有自己的 TensorRT Engine。它接在生成之後、送出之前,放大時會補出邊緣和紋理。模型固定放大 4 倍,再縮放到設定的輸出解析度,所以實際有兩種用法:

模式 設定 做法
4 倍 生成 512×512,輸出 2048×2048 直接送出模型的 4 倍畫面
2 倍 生成 512×512,輸出 1024×1024 模型放大 4 倍後再縮成一半

只要輸出解析度大於生成解析度,Upscaler 預設就會執行。在設定檔寫 upscaler = false 或在 Web Panel 關掉,就改回一般縮放。下圖左右都是 2048×2048 的輸出,裁出同一塊區域比較:

同一格 2048×2048 輸出的裁切對照,左邊一般縮放的橘色花瓣和藍紫色塊交界較柔,右邊經 Upscaler 放大的邊緣比較銳利

畫質的代價是速度。以下數據都在同一台電腦量測,條件固定:

項目 設定
顯示卡 RTX 3070 8 GB,驅動 621.01
功率上限 162 W,這張卡預設 270 W 的 60%
生成 512×512
畫面設定 預設的提示詞,Strength 0.68,Temporal Coherence 開啟

我用 streamturbo bench 測了四種輸出。bench 用一張固定的參考圖跑 300 格,量 StreamTurbo 本身的速度,不經過 NDI 或 Spout,每種跑兩輪取平均。p50 是中位數,一半的影格比這個值快:

輸出 放大方式 每秒格數 每格處理時間 p50
512×512 不放大 30.4 fps 32.1 ms
2048×2048 一般縮放 26.2 fps 37.3 ms
1024×1024 Upscaler 2 倍 22.3 fps 44.2 ms
2048×2048 Upscaler 4 倍 21.3 fps 46.0 ms

同樣輸出 2048×2048,Upscaler 每格多花約 9 ms,每秒格數從 26.2 降到 21.3。2 倍和 4 倍的差距不到 2 ms,因為兩者跑的是同一個 4 倍模型。用不到 2048 時,用 2 倍就好。

TensorRT 加速與傳輸延遲

Web Panel 上的 Backend 代表 StreamTurbo 用哪一種方式執行模型。同樣是 512×512 生成、Upscaler 放大到 2048×2048,TensorRT 和 PyTorch 的差距如下。PyTorch 就是第一次啟動、Engine 還在建置時的速度:

Backend 每秒格數 每格處理時間 p50 整張顯示卡 VRAM 用量
TensorRT 21.3 fps 46.0 ms 5.8 GiB
PyTorch 11.7 fps 84.6 ms 4.0 GiB

VRAM 是整張顯示卡的用量,包含桌面與其他程式在閒置時就佔用的約 1.1 GiB。TensorRT 比 PyTorch 快將近一倍,代價是 Engine 多佔約 1.8 GiB。

實際接上 TD 時,我在測試用的 TD 專案裡用範例元件的 Measure Latency 量 Round-trip 延遲,每種傳輸量兩次,每次 10 個來回。執行中的每秒格數與每格處理時間取自同一頁的 Status:

傳輸 Round-trip 平均 最小 最大 執行中的每秒格數 每格處理時間 p50
Spout 153–162 ms 133 ms 183 ms 14.4 fps 67 ms
NDI 428–430 ms 400 ms 467 ms 約 16 fps 61–63 ms

同一台電腦上,Spout 的延遲不到 NDI 的一半,要讓畫面跟著動作走就用 Spout。不過兩者的每格處理時間都比 bench 的 46 ms 長,每秒格數也只剩 14 到 16。2048×2048 的 RGBA 影格每格約 16 MB,我推測是收送這些影格的拷貝和生成搶用顯示卡。覺得不夠流暢時,可以把輸出降成 Upscaler 2 倍的 1024×1024。

4 GB 顯示卡也跑得動

VRAM 不到 6 GB 的顯示卡會自動進入 Low-VRAM Mode。Low-VRAM Mode 是為小顯示卡準備的省記憶體模式,建置 Engine 時會暫停輸出、獨占顯示卡,生成解析度上限是每邊 512,設定超過時只在內部維持比例縮小,Web Panel 上的設定和送回 TD 的輸出解析度都不變。本文用的 512×512 生成本來就在上限內,不會被縮小。每次啟動載入已建好的 Engine 時,輸出會停頓幾秒。

我借了一台 RTX 3050 Laptop(4 GB VRAM)實際跑過,當時 TD 同時開著,經 Spout 把畫面送進 StreamTurbo。啟動時自動進入 Low-VRAM Mode,Engine 全部建置成功並切換到 TensorRT。Web Panel 的設定和在 3070 上一樣,Upscaler 也開著,畫面解析度沒有變,只有每秒格數下降。那次用的是預設解析度,生成設定 1024×768 超過上限,內部以 512×384 生成,再用 Upscaler 放大回 1024×768 輸出。以下是 Web Panel 上的數字:

Backend 每秒格數 每格處理時間 p50 p95 整張顯示卡 VRAM 用量 顯示卡功耗
TensorRT 5.8 fps 163 ms 168 ms 3.9/4.0 GiB 40 W

p95 表示 95% 的影格在這個時間內完成。同樣的 512×384 加 Upscaler,RTX 3070 在 60% 功率上限下 p50 是 26.6 ms,筆電約慢 6 倍。可以用,但明顯比較慢,比較適合先在筆電上試效果。那台筆電的 Engine 建置時間沒有量到,完整紀錄在 GitHub issue #28。

問題排除

狀況 處理方式
Web Panel 狀態一直是 waiting 用 .venv\Scripts\streamturbo run --list-sources 確認來源名稱,NDI 另需確認防火牆允許
Spout Out 顯示 Sender Name 已被使用 換一個名稱,或重新啟動 TD 釋放殘留的名稱
重新啟動 StreamTurbo 後,TD 收到的畫面停住 TD 的 Spout In 還連著上一次的發送端,在範例元件上重新選一次 Transport
整台電腦變慢,每秒格數掉到個位數 在 Web Panel 看 VRAM 是否接近上限,接近時關掉其他吃 VRAM 的程式,或把輸出改成 Upscaler 2 倍
改了提示詞或 Strength 卻慢慢才變 這是 prompt_transition 和 strength_glide 的漸變,要立刻切換時設成 0

還有一個沒查出原因的問題。在那台 RTX 3050 Laptop 上,TD 專案換成粒子特效比較複雜的版本後,StreamTurbo 經 Spout 接收第一格畫面就直接結束,沒有錯誤訊息,Windows 的錯誤紀錄指向 Spout 的 DLL。當時因為時間壓力沒有繼續排查,改用 NDI 就正常運作。如果 StreamTurbo 一接上 Spout 就關閉,可以先改用 NDI。

開發過程

StreamTurbo 全程由 Claude Opus 5.5 搭配 Matt Pocock Skills 開發。每個功能先在 GitHub issue 寫成 spec(功能規格),再拆成一張張可以單獨完成的票。4 份 spec 一共拆成 13 張票,其中 11 張交給 AI Agent 實作,剩下 2 張是我在 4 GB 筆電上做的實機重現與量測。開發時用的流程,後來我整理成 Whetstone。

總結

StreamTurbo 適合想在 TD 做即時 AI 影像,又不想處理 Python 與 CUDA 版本的人。在 RTX 3070、功率上限 60% 的環境下,512×512 生成再用 Upscaler 放大到 2048×2048 約 21 fps,比一般縮放少約 5 fps,換到比較清楚的邊緣與紋理。

  • 優點:雙擊 start.cmd 就裝好,刪掉資料夾就移除乾淨,內建 Upscaler 與 TD 範例元件,4 GB 顯示卡也能用 TensorRT。
  • 缺點:只支援 Windows 與 NVIDIA 顯示卡,只有 sd-turbo,沒有 ControlNet、LoRA 與 SDXL。
  • 尚未驗證:其他顯示卡型號的速度,以及 4 GB 顯示卡的 Engine 建置時間。

接著可以做什麼

下一篇Whetstone:專為 Claude Code 改寫的 Matt Pocock SkillsAI
Ted Liou

Ted Liou

Unity 現役工程師,Unity、AI 技術開發經驗分享與諮詢。