Instructions to use BAAI/Brainmu-SpikeCamera with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use BAAI/Brainmu-SpikeCamera with Transformers:
# pip install -U transformers accelerate # Load model directly from transformers import SpikeConvFrontend model = SpikeConvFrontend.from_pretrained("BAAI/Brainmu-SpikeCamera", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Download src/ui/index.html from BAAI/Brainmu-SpikeCamera: direct link, hf CLI and curl.
- Browser
- Download file 13.9 kB
-
https://huggingface.co/BAAI/Brainmu-SpikeCamera/resolve/main/src/ui/index.html
- Command line
-
hf download hf://BAAI/Brainmu-SpikeCamera/src/ui/index.html
-
curl -L -o index.html https://huggingface.co/BAAI/Brainmu-SpikeCamera/resolve/main/src/ui/index.html
13.9 kB
| <html lang="zh-CN"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Brainmu 重构测试台</title> | |
| <style> | |
| :root{font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC",sans-serif;color:#142b3c;background:#f3f6f8;font-size:14px}*{box-sizing:border-box}body{margin:0}header{background:#102c3d;color:#fff;padding:24px 36px;display:flex;justify-content:space-between;align-items:center}h1{font-size:23px;margin:0 0 7px;letter-spacing:-.4px}header p{margin:0;color:#b8cbd7}.pill{border:1px solid #476271;border-radius:20px;padding:8px 14px;font-size:12px}main{max-width:1580px;margin:24px auto;padding:0 28px;display:grid;grid-template-columns:320px minmax(0,1fr);gap:22px}.card{background:white;border:1px solid #dce5eb;border-radius:14px;padding:20px;box-shadow:0 3px 10px #193d5210;margin-bottom:18px}h2{font-size:16px;margin:0 0 16px;display:flex;align-items:center;gap:10px}.step{display:inline-grid;place-items:center;background:#e7f4f1;color:#087765;border-radius:8px;width:28px;height:28px}.muted,small{color:#526b7a;line-height:1.7}label{display:block;font-size:12px;font-weight:600;margin:12px 0 6px}input,select,textarea{font:inherit;border:1px solid #bacbd5;border-radius:7px;padding:10px;width:100%;background:#fff;color:#17384c}input{font-size:12px}textarea{resize:vertical;min-height:86px;line-height:1.5}button,.link{font:inherit;border:1px solid #bacbd5;border-radius:8px;background:white;color:#244454;padding:11px 14px;min-height:44px;cursor:pointer;text-decoration:none;display:inline-block}button:hover,.link:hover{background:#edf6f5}button.primary{background:#087c6b;color:white;border-color:#087c6b;width:100%;margin-top:14px;font-weight:600}button:disabled{opacity:.42;cursor:not-allowed}button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible{outline:3px solid #43aeeb;outline-offset:2px}.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}.metric{font-size:30px;font-weight:650;margin-top:12px;font-variant-numeric:tabular-nums}.metric span{font-size:13px;font-weight:400;color:#5d7380}.full{border-top:3px solid #087c6b}.status{display:flex;justify-content:space-between;gap:10px;margin-bottom:12px}.bar{height:7px;background:#e6edef;border-radius:8px;overflow:hidden}.bar div{height:100%;background:#0e937e;transition:width .4s}#error{color:#a02632;white-space:pre-wrap;word-break:break-word}#error:empty{display:none}.gallery{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}.frame{margin:0;min-width:0}.frame img{width:100%;aspect-ratio:1.6;object-fit:contain;border-radius:8px;background:#e9eff3;border:1px solid #dae3e9}.frame img:not([src]){visibility:hidden}.frame .well{background:#edf2f5;border-radius:8px;aspect-ratio:1.6}.frame figcaption{margin:10px 0;color:#456170;font-size:12px}.toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.toolbar input{max-width:220px}.scroll{max-height:350px;overflow:auto;margin-top:14px}table{width:100%;border-collapse:collapse;font-size:13px}th{text-align:left;color:#536d7d;background:#f6f8fa;position:sticky;top:0}td,th{padding:11px 12px;border-bottom:1px solid #e6edf1}td{font-variant-numeric:tabular-nums}tr.selected td{background:#e8f6f2}td button{padding:2px 0;border:0;min-height:28px;color:#087c6b;background:transparent;text-align:left}details summary{cursor:pointer;color:#486575;font-size:12px;margin-top:12px}footer{font-size:12px;color:#5a7180;line-height:1.8;word-break:break-all}.actions{display:flex;gap:8px;margin-top:10px}.empty{padding:18px;text-align:center;color:#677e8b}.result-title{font-size:13px;color:#476572;margin-bottom:14px;min-height:18px} | |
| @media(max-width:1000px){main{grid-template-columns:1fr;padding:0 16px}aside{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}header{padding:20px}.gallery{gap:8px}} | |
| @media(max-width:700px){aside{display:block}.stats{grid-template-columns:1fr}.gallery{grid-template-columns:1fr}header .pill{display:none}.metric{font-size:26px}} | |
| @media(prefers-reduced-motion:reduce){*{transition:none!important}} | |
| </style> | |
| <header><div><h1>Brainmu 重构测试台</h1><p>加载脉冲数据,查看逐图重构质量与整体评测结果</p></div><div class="pill">默认 8 卡并行 · LoRA 2,000 steps</div></header> | |
| <main><aside> | |
| <section class="card"><h2><span class="step">1</span>加载模型</h2><p class="muted" id="modelStatus">Brainmu + 生成专家 LoRA + 卷积模块</p><details><summary>查看 / 修改服务器模型路径</summary><label for="model_path">Brainmu 模型目录</label><input id="model_path"><label for="adapter">LoRA 权重</label><input id="adapter"><label for="frontend">卷积模块权重</label><input id="frontend"></details><label for="gpu_count">并行 GPU 数量(加载前选择)</label><select id="gpu_count"><option value="8">8 卡并行(默认)</option><option value="4">4 卡并行</option><option value="2">2 卡并行</option><option value="1">单卡</option></select><button class="primary" id="loadModel">加载模型到 GPU</button><small>加载完成后模型常驻显存,后续测试无需重复加载。</small></section> | |
| <section class="card"><h2><span class="step">2</span>加载测试数据</h2><p class="muted">测试集:1,000 对 DAT / GT。</p><details><summary>查看 / 修改服务器数据路径</summary><label for="spike_dir">DAT 文件夹</label><input id="spike_dir"><label for="gt_dir">对应 GT 文件夹</label><input id="gt_dir"></details><button class="primary" id="loadData">加载 1,000 对测试数据</button><small id="dataStatus">41帧 · 400 × 250 · 同名 GT 配对</small></section> | |
| <section class="card"><h2><span class="step">3</span>开始评测</h2><label for="limit">测试数量</label><select id="limit"><option value="1000">完整 1,000 张</option><option value="16">16 张 · 8 卡验证</option><option value="3">前 3 张快速试跑</option></select><button class="primary" id="run">开始测试</button><div class="actions"><button id="stop">停止测试</button></div><label for="prompt">Prompt · 重构提示词</label><textarea id="prompt" maxlength="2000">Restore the clean image.</textarea><small>开始测试时固定本轮提示词;修改只影响下一轮。</small><p class="muted" id="activePrompt"></p><p class="muted"><span id="inferenceSteps"></span> 步采样 · 灰度 PSNR / SSIM<br>完整测试默认 8 卡,每卡 125 张;seed 按全局样本序号固定。</p></section> | |
| </aside><article> | |
| <div class="stats"><section class="card"><small>已完成 / 本次计划</small><div class="metric" id="count">0 <span>/ —</span></div></section><section class="card"><small>已完成样本 · 平均 PSNR</small><div class="metric" id="mean">— <span>dB</span></div></section><section class="card full"><small>完整 1,000 张 · 平均 PSNR</small><div class="metric" id="fullMean">— <span>dB</span></div><small id="fullHint">完整测试结束后显示</small></section></div> | |
| <section class="card"><div class="status"><strong id="message" aria-live="polite">正在连接服务器…</strong><span class="muted" id="elapsed"></span></div><div class="bar"><div id="progress" style="width:0"></div></div><p id="error" role="alert"></p></section> | |
| <section class="card"><div class="toolbar"><h2>样本对比</h2><span class="muted">点击下方样本查看</span></div><div class="result-title" id="selectedLabel">暂无结果,开始测试后将在这里展示。</div><div class="gallery"> | |
| <figure class="frame"><div class="well"><img id="condition" alt="输入的 41 帧二值 spike 动图"></div><figcaption>输入 Spike · 41 帧动图(慢放)</figcaption></figure> | |
| <figure class="frame"><div class="well"><img id="prediction" alt="Brainmu LoRA 重构输出"></div><figcaption>Brainmu LoRA · RGB 重构</figcaption></figure> | |
| <figure class="frame"><div class="well"><img id="gt" alt="样本对应清晰 GT"></div><figcaption>清晰参考 · GT(灰度)</figcaption></figure> | |
| </div></section> | |
| <section class="card"><div class="toolbar"><h2 style="margin:0">逐图指标</h2><input id="search" aria-label="搜索样本名称" placeholder="搜索样本名称…"><div><a class="link" href="/download?format=csv" id="csv">下载 CSV</a> <a class="link" href="/download?format=json" id="json">下载 JSON</a></div></div><div class="scroll"><table><thead><tr><th>#</th><th>样本</th><th>PSNR ↑</th><th>SSIM ↑</th></tr></thead><tbody id="rows"></tbody></table><div class="empty" id="empty">还没有测试结果</div></div><small>PSNR 为逐图灰度 PSNR 的算术平均;中途停止 / 3 张试跑不代表完整 1,000 张结果。</small></section> | |
| <footer>输入:41 帧 Spike → 卷积重构模块 → Brainmu → RGB 重构图像。GT 仅用于指标计算,不作为模型输入。<br><span id="outputDir">新测试会写入独立文件夹,保留已有实验。</span></footer> | |
| </article></main> | |
| <script> | |
| const $=id=>document.getElementById(id);let state=null,selected=-1,viewKey='',initialized=false,inFlight=false;const fmt=(n,d=3)=>n==null?'—':n.toFixed(d); | |
| async function act(endpoint,payload={}){try{const r=await fetch('/api/'+endpoint,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});const d=await r.json();if(!r.ok)throw Error(d.error);await poll()}catch(e){$('error').textContent=e.message}} | |
| function paths(keys){return Object.fromEntries(keys.map(k=>[k,$(k).value]))} | |
| $('loadModel').onclick=()=>act('load',{...paths(['model_path','adapter','frontend']),gpu_count:Number($('gpu_count').value)}); | |
| $('loadData').onclick=()=>act('dataset',paths(['spike_dir','gt_dir'])); | |
| $('run').onclick=()=>{selected=-1;viewKey='';act('run',{limit:Number($('limit').value),prompt:$('prompt').value})}; | |
| $('stop').onclick=()=>act('stop'); | |
| function preview(){const row=state.rows[selected];if(!row){$('selectedLabel').textContent='暂无结果,开始测试后将在这里展示。';for(const k of ['condition','prediction','gt'])$(k).removeAttribute('src');return} | |
| const key=state.run_dir+':'+selected;if(viewKey===key)return;viewKey=key; | |
| $('selectedLabel').textContent=row.id+' · PSNR '+fmt(row.psnr_db)+' dB · SSIM '+fmt(row.ssim,4); | |
| $('condition').src='http://127.0.0.1:8998/spike?id='+encodeURIComponent(row.id); | |
| $('gt').src='http://127.0.0.1:8998/gt?id='+encodeURIComponent(row.id); | |
| $('prediction').src='/image?i='+selected+'&kind=prediction&run='+encodeURIComponent(state.run_dir)} | |
| function table(){const q=$('search').value.trim().toLowerCase();const fragment=document.createDocumentFragment();let n=0; | |
| for(const [i,r] of [...state.rows.entries()].sort((a,b)=>a[1].index-b[1].index)){if(!r.id.toLowerCase().includes(q))continue;n++;const tr=document.createElement('tr');if(i===selected)tr.className='selected'; | |
| const values=[String(r.index+1),r.id,fmt(r.psnr_db)+' dB',fmt(r.ssim,4)];for(let j=0;j<values.length;j++){const td=document.createElement('td');if(j===1){const b=document.createElement('button');b.textContent=values[j];b.onclick=()=>{selected=i;preview();table()};td.append(b)}else td.textContent=values[j];tr.append(td)}fragment.append(tr)} | |
| $('rows').replaceChildren(fragment);$('empty').style.display=n?'none':'block';$('empty').textContent=state.rows.length?'没有匹配的样本':'还没有测试结果'} | |
| $('search').oninput=()=>state&&table(); | |
| async function poll(){if(inFlight)return;inFlight=true;try{const r=await fetch('/api/state');if(!r.ok)throw Error('服务器连接失败');const s=await r.json();if(!initialized){for(const [k,v] of Object.entries(s.defaults))$(k).value=v;$('prompt').value=s.inference_settings.prompt;$('inferenceSteps').textContent=s.inference_settings.steps;initialized=true} | |
| const changed=!state||state.rows.length!==s.rows.length||state.run_dir!==s.run_dir;state=s; | |
| const busy=['loading','validating','running'].includes(s.phase); | |
| $('loadModel').disabled=busy||s.model_loaded;$('loadData').disabled=busy||!s.model_loaded;$('run').disabled=busy||!s.model_loaded||s.dataset_count!==1000||!s.prompt_supported||!s.parallel_supported;$('stop').disabled=s.phase!=='running'; | |
| for(const k of ['model_path','adapter','frontend','gpu_count'])$(k).disabled=busy||s.model_loaded; | |
| for(const k of ['spike_dir','gt_dir','limit','prompt'])$(k).disabled=busy; | |
| $('modelStatus').textContent=s.model_loaded?'模型已就绪 · '+(s.gpu_count||1)+' 卡常驻':s.phase==='loading'?'正在加载,请稍候…':'Brainmu + 生成专家 LoRA + 卷积模块'; | |
| $('loadModel').textContent=s.model_loaded?'模型已加载':'加载模型到 GPU'; | |
| $('dataStatus').textContent=s.dataset_count?'已验证 '+s.dataset_count+' 对 DAT / GT':'41帧 · 400 × 250 · 同名 GT 配对'; | |
| $('message').textContent=s.message.replaceAll('Brainmu','Brainmu');$('activePrompt').textContent=s.requested?'本轮 Prompt:'+(s.run_prompt||'Restore the clean image.') : '';$('error').textContent=s.error;$('elapsed').textContent=s.started?Math.round(s.elapsed)+' 秒':''; | |
| $('count').innerHTML=s.completed+' <span>/ '+(s.requested||'—')+'</span>';$('mean').innerHTML=fmt(s.mean_psnr)+' <span>dB</span>'; | |
| $('fullMean').innerHTML=(s.full_1000_complete?fmt(s.mean_psnr):'—')+' <span>dB</span>'; | |
| $('fullHint').textContent=s.full_1000_complete?'完整测试完成 · SSIM '+fmt(s.mean_ssim,4):'完整测试结束后显示'; | |
| $('progress').style.width=(s.requested?100*s.completed/s.requested:0)+'%'; | |
| $('outputDir').textContent=s.run_dir?'结果目录:'+s.run_dir:'新测试会写入独立文件夹,保留已有实验。'; | |
| for(const k of ['csv','json']){$(k).style.pointerEvents=s.run_dir?'auto':'none';$(k).style.opacity=s.run_dir?'1':'.4'} | |
| if(changed){if(selected<0&&s.rows.length)selected=0;if(selected>=s.rows.length)selected=-1;preview();table()} | |
| }catch(e){$('error').textContent='连接中断:'+e.message+'。请确认 SSH 转发仍在运行。'}finally{inFlight=false}} | |
| poll();setInterval(poll,1500); | |
| </script></html> | |