feat(ui): add article TOC and interactive VRAM calculator for Wan 2.2
Deploy / build (push) Successful in 22s
Deploy / build (push) Successful in 22s
This commit is contained in:
1 parent
0dae8b0daa
commit
2c10cad52b
4 files changed
+609
-1
No files matched your search
@@ -43,6 +43,234 @@ banner: /banners/running-ai-video-locally-on-a-12gb-gpu.jpg
|
||||
|
||||
像素数减半,时间不是减半,而是降到约三分之一。这是扩散 Transformer 典型的超线性关系,也正是 480p 这档草稿存在的理由。
|
||||
|
||||
<div class="interactive-calc" id="wan-vram-calc">
|
||||
<div class="calc-header">
|
||||
<span class="calc-badge">交互工具</span>
|
||||
<h4>Wan 2.2 TI2V-5B 渲染时间与显存估算器</h4>
|
||||
<p>基于 RTX 3060 12GB 实测基准数据,实时模拟不同分辨率、秒数与步数下的采样时长、显存需求与分段策略。</p>
|
||||
</div>
|
||||
<div class="calc-grid">
|
||||
<div class="calc-field">
|
||||
<label for="calc-res">生成分辨率档位</label>
|
||||
<select id="calc-res">
|
||||
<option value="480">832×480(快速草稿档 — 约 6 分钟 / 5秒)</option>
|
||||
<option value="704" selected>1280×704(生产基础档 — 约 18 分钟 / 5秒)</option>
|
||||
<option value="736">1280×736(32整倍数,真1080p — 约 19.5 分钟 / 5秒)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="calc-field">
|
||||
<label for="calc-sec">镜头时长(秒)</label>
|
||||
<div class="calc-slider-wrap">
|
||||
<input type="range" id="calc-sec" min="1" max="10" step="1" value="5">
|
||||
<span class="calc-val" id="calc-sec-val">5 秒(121 帧 @ 24fps)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calc-field">
|
||||
<label for="calc-steps">采样步数(Steps)</label>
|
||||
<div class="calc-slider-wrap">
|
||||
<input type="range" id="calc-steps" min="10" max="30" step="5" value="20">
|
||||
<span class="calc-val" id="calc-steps-val">20 步</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calc-results">
|
||||
<div class="calc-stat">
|
||||
<span class="stat-label">预估总渲染耗时</span>
|
||||
<span class="stat-num" id="stat-time">~17.9 分钟</span>
|
||||
<span class="stat-sub" id="stat-breakdown">15.1分 采样 + 2.8分 解码</span>
|
||||
</div>
|
||||
<div class="calc-stat">
|
||||
<span class="stat-label">峰值显存占用</span>
|
||||
<span class="stat-num" id="stat-vram">12.1 GB</span>
|
||||
<span class="stat-sub" id="stat-vram-note">12GB 显卡极限贴线</span>
|
||||
</div>
|
||||
<div class="calc-stat">
|
||||
<span class="stat-label">SeedVR2 1.5× 放大分段策略</span>
|
||||
<span class="stat-num" id="stat-split">3 个切片</span>
|
||||
<span class="stat-sub" id="stat-split-note">每段 ≤41 帧,防止原生崩溃</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.interactive-calc {
|
||||
margin: 2.2rem 0;
|
||||
padding: 1.4rem;
|
||||
border-radius: var(--radius, 8px);
|
||||
background: var(--surface, #16181d);
|
||||
border: 1px solid var(--border, #2d3139);
|
||||
}
|
||||
.calc-header {
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
.calc-badge {
|
||||
display: inline-block;
|
||||
padding: 0.15rem 0.5rem;
|
||||
font-size: 0.72rem;
|
||||
font-family: var(--font-mono);
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
color: var(--brand, #6d8dff);
|
||||
background: rgba(109, 141, 255, 0.12);
|
||||
border-radius: 4px;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.calc-header h4 {
|
||||
margin: 0.2rem 0 0.4rem;
|
||||
font-size: 1.15rem;
|
||||
color: var(--text, #e2e8f0);
|
||||
}
|
||||
.calc-header p {
|
||||
margin: 0;
|
||||
font-size: 0.88rem;
|
||||
color: var(--muted, #94a3b8);
|
||||
}
|
||||
.calc-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 1.1rem;
|
||||
margin-bottom: 1.4rem;
|
||||
}
|
||||
.calc-field label {
|
||||
display: block;
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
color: var(--muted, #94a3b8);
|
||||
margin-bottom: 0.45rem;
|
||||
}
|
||||
.calc-field select {
|
||||
width: 100%;
|
||||
padding: 0.55rem 0.75rem;
|
||||
border-radius: 6px;
|
||||
background: var(--bg, #0b0c0e);
|
||||
border: 1px solid var(--border, #2d3139);
|
||||
color: var(--text, #e2e8f0);
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
.calc-slider-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.calc-slider-wrap input[type="range"] {
|
||||
width: 100%;
|
||||
accent-color: var(--brand, #6d8dff);
|
||||
cursor: pointer;
|
||||
}
|
||||
.calc-val {
|
||||
font-size: 0.82rem;
|
||||
font-family: var(--font-mono);
|
||||
color: var(--brand, #6d8dff);
|
||||
}
|
||||
.calc-results {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 1rem;
|
||||
padding-top: 1.2rem;
|
||||
border-top: 1px solid var(--border, #2d3139);
|
||||
}
|
||||
.calc-stat {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
color: var(--muted, #94a3b8);
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.stat-num {
|
||||
font-size: 1.35rem;
|
||||
font-weight: 700;
|
||||
font-family: var(--font-mono);
|
||||
color: var(--text, #e2e8f0);
|
||||
}
|
||||
.stat-sub {
|
||||
font-size: 0.78rem;
|
||||
color: var(--muted, #94a3b8);
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.interactive-calc { padding: 1rem; }
|
||||
.calc-results { grid-template-columns: 1fr; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
(function initCalc() {
|
||||
const resEl = document.getElementById('calc-res');
|
||||
const secEl = document.getElementById('calc-sec');
|
||||
const secVal = document.getElementById('calc-sec-val');
|
||||
const stepsEl = document.getElementById('calc-steps');
|
||||
const stepsVal = document.getElementById('calc-steps-val');
|
||||
const timeEl = document.getElementById('stat-time');
|
||||
const bdEl = document.getElementById('stat-breakdown');
|
||||
const vramEl = document.getElementById('stat-vram');
|
||||
const vramNote = document.getElementById('stat-vram-note');
|
||||
const splitEl = document.getElementById('stat-split');
|
||||
const splitNote = document.getElementById('stat-split-note');
|
||||
|
||||
if (!resEl || !secEl || !stepsEl) return;
|
||||
|
||||
function update() {
|
||||
const res = resEl.value;
|
||||
const sec = parseInt(secEl.value, 10);
|
||||
const steps = parseInt(stepsEl.value, 10);
|
||||
|
||||
const frames = sec === 1 ? 25 : (sec - 1) * 24 + 25;
|
||||
secVal.textContent = `${sec} 秒(${frames} 帧 @ 24fps)`;
|
||||
stepsVal.textContent = `${steps} 步`;
|
||||
|
||||
let baseSamplePerFrameStep = 0;
|
||||
let baseDecodePerFrame = 0;
|
||||
let vramPeak = 0;
|
||||
|
||||
if (res === '480') {
|
||||
baseSamplePerFrameStep = 4.8 / (121 * 20);
|
||||
baseDecodePerFrame = 1.3 / 121;
|
||||
vramPeak = 10.3;
|
||||
} else if (res === '704') {
|
||||
baseSamplePerFrameStep = 15.1 / (121 * 20);
|
||||
baseDecodePerFrame = 2.8 / 121;
|
||||
vramPeak = 12.1;
|
||||
} else {
|
||||
baseSamplePerFrameStep = 16.5 / (121 * 20);
|
||||
baseDecodePerFrame = 3.0 / 121;
|
||||
vramPeak = 12.2;
|
||||
}
|
||||
|
||||
const sampleTime = frames * steps * baseSamplePerFrameStep;
|
||||
const decodeTime = frames * baseDecodePerFrame;
|
||||
const totalTime = sampleTime + decodeTime;
|
||||
|
||||
timeEl.textContent = `~${totalTime.toFixed(1)} 分钟`;
|
||||
bdEl.textContent = `${sampleTime.toFixed(1)}分 采样 + ${decodeTime.toFixed(1)}分 解码`;
|
||||
|
||||
vramEl.textContent = `${vramPeak} GB`;
|
||||
if (vramPeak > 12.0) {
|
||||
vramNote.textContent = '需要开启分块 VAE 解码才能跑通 12GB';
|
||||
vramNote.style.color = '#f59e0b';
|
||||
} else {
|
||||
vramNote.textContent = '缓存清理后可直接装进 12GB';
|
||||
vramNote.style.color = 'var(--muted)';
|
||||
}
|
||||
|
||||
const segments = Math.ceil(frames / 41);
|
||||
splitEl.textContent = `${segments} 个切片`;
|
||||
if (frames > 41) {
|
||||
splitNote.textContent = '必须切成 ≤41 帧(防止原生异常崩溃)';
|
||||
} else {
|
||||
splitNote.textContent = '单次直出安全(≤41 帧)';
|
||||
}
|
||||
}
|
||||
|
||||
resEl.addEventListener('change', update);
|
||||
secEl.addEventListener('input', update);
|
||||
stepsEl.addEventListener('input', update);
|
||||
update();
|
||||
})();
|
||||
</script>
|
||||
|
||||
## 第一次失败:解码把主机内存吃光
|
||||
|
||||
第一次 720p 采样很顺利,然后死在 VAE 解码:
|
||||
|
||||
Reference in new issue
Block a user