Spaces:
Running
Running
| <html lang="zh-CN"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>TP DP PP 可视化分析</title> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --primary-color: #3a86ff; | |
| --secondary-color: #8338ec; | |
| --success-color: #38b000; | |
| --warning-color: #ff9e00; | |
| --danger-color: #ff006e; | |
| --dark-color: #2b2d42; | |
| --light-color: #f8f9fa; | |
| --gray-color: #6c757d; | |
| --border-radius: 12px; | |
| --box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12); | |
| --transition: all 0.3s ease; | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| } | |
| body { | |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
| color: var(--dark-color); | |
| min-height: 100vh; | |
| padding: 20px; | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| } | |
| header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 20px 0; | |
| margin-bottom: 30px; | |
| border-bottom: 1px solid rgba(0, 0, 0, 0.1); | |
| } | |
| .logo { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| font-size: 1.8rem; | |
| font-weight: 700; | |
| color: var(--primary-color); | |
| } | |
| .logo i { | |
| font-size: 2.2rem; | |
| } | |
| .anycoder-link { | |
| color: var(--secondary-color); | |
| text-decoration: none; | |
| font-size: 0.9rem; | |
| font-weight: 500; | |
| transition: var(--transition); | |
| } | |
| .anycoder-link:hover { | |
| color: var(--primary-color); | |
| text-decoration: underline; | |
| } | |
| h1 { | |
| text-align: center; | |
| margin-bottom: 10px; | |
| color: var(--dark-color); | |
| font-size: 2.5rem; | |
| } | |
| .subtitle { | |
| text-align: center; | |
| margin-bottom: 40px; | |
| color: var(--gray-color); | |
| font-size: 1.1rem; | |
| } | |
| .controls { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 20px; | |
| margin-bottom: 40px; | |
| justify-content: center; | |
| } | |
| .control-group { | |
| background: white; | |
| padding: 20px; | |
| border-radius: var(--border-radius); | |
| box-shadow: var(--box-shadow); | |
| flex: 1; | |
| min-width: 250px; | |
| max-width: 350px; | |
| } | |
| .control-group h3 { | |
| margin-bottom: 15px; | |
| color: var(--primary-color); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .control-group h3 i { | |
| font-size: 1.2rem; | |
| } | |
| .slider-container { | |
| margin-bottom: 15px; | |
| } | |
| .slider-container label { | |
| display: block; | |
| margin-bottom: 8px; | |
| font-weight: 500; | |
| } | |
| .slider { | |
| width: 100%; | |
| height: 8px; | |
| -webkit-appearance: none; | |
| background: #e0e0e0; | |
| border-radius: 4px; | |
| outline: none; | |
| } | |
| .slider::-webkit-slider-thumb { | |
| -webkit-appearance: none; | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 50%; | |
| background: var(--primary-color); | |
| cursor: pointer; | |
| transition: var(--transition); | |
| } | |
| .slider::-webkit-slider-thumb:hover { | |
| transform: scale(1.2); | |
| } | |
| .slider-value { | |
| text-align: right; | |
| font-weight: 600; | |
| color: var(--primary-color); | |
| margin-top: 5px; | |
| } | |
| .visualization { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); | |
| gap: 30px; | |
| margin-bottom: 40px; | |
| } | |
| .chart-container { | |
| background: white; | |
| padding: 25px; | |
| border-radius: var(--border-radius); | |
| box-shadow: var(--box-shadow); | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .chart-container h3 { | |
| margin-bottom: 20px; | |
| color: var(--dark-color); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .chart { | |
| height: 300px; | |
| position: relative; | |
| display: flex; | |
| align-items: flex-end; | |
| justify-content: center; | |
| gap: 20px; | |
| margin-bottom: 20px; | |
| } | |
| .bar { | |
| width: 60px; | |
| border-radius: 8px 8px 0 0; | |
| transition: var(--transition); | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: white; | |
| font-weight: 600; | |
| } | |
| .bar-tp { | |
| background: var(--primary-color); | |
| } | |
| .bar-dp { | |
| background: var(--secondary-color); | |
| } | |
| .bar-pp { | |
| background: var(--success-color); | |
| } | |
| .bar-label { | |
| position: absolute; | |
| bottom: -30px; | |
| left: 0; | |
| right: 0; | |
| text-align: center; | |
| font-weight: 600; | |
| color: var(--dark-color); | |
| } | |
| .metrics { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | |
| gap: 20px; | |
| margin-bottom: 40px; | |
| } | |
| .metric-card { | |
| background: white; | |
| padding: 25px; | |
| border-radius: var(--border-radius); | |
| box-shadow: var(--box-shadow); | |
| text-align: center; | |
| transition: var(--transition); | |
| } | |
| .metric-card:hover { | |
| transform: translateY(-5px); | |
| } | |
| .metric-card i { | |
| font-size: 2.5rem; | |
| margin-bottom: 15px; | |
| } | |
| .metric-card.tp i { | |
| color: var(--primary-color); | |
| } | |
| .metric-card.dp i { | |
| color: var(--secondary-color); | |
| } | |
| .metric-card.pp i { | |
| color: var(--success-color); | |
| } | |
| .metric-card h3 { | |
| margin-bottom: 10px; | |
| font-size: 1.2rem; | |
| } | |
| .metric-value { | |
| font-size: 2rem; | |
| font-weight: 700; | |
| margin-bottom: 10px; | |
| } | |
| .metric-description { | |
| color: var(--gray-color); | |
| font-size: 0.9rem; | |
| } | |
| .comparison { | |
| background: white; | |
| padding: 25px; | |
| border-radius: var(--border-radius); | |
| box-shadow: var(--box-shadow); | |
| margin-bottom: 40px; | |
| } | |
| .comparison h3 { | |
| margin-bottom: 20px; | |
| color: var(--dark-color); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .comparison-chart { | |
| height: 200px; | |
| display: flex; | |
| align-items: flex-end; | |
| gap: 15px; | |
| justify-content: center; | |
| } | |
| .comparison-bar { | |
| flex: 1; | |
| border-radius: 8px 8px 0 0; | |
| transition: var(--transition); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: white; | |
| font-weight: 600; | |
| max-width: 150px; | |
| } | |
| footer { | |
| text-align: center; | |
| padding: 20px; | |
| color: var(--gray-color); | |
| font-size: 0.9rem; | |
| border-top: 1px solid rgba(0, 0, 0, 0.1); | |
| } | |
| @media (max-width: 768px) { | |
| .visualization { | |
| grid-template-columns: 1fr; | |
| } | |
| .metrics { | |
| grid-template-columns: 1fr; | |
| } | |
| h1 { | |
| font-size: 2rem; | |
| } | |
| .controls { | |
| flex-direction: column; | |
| } | |
| .control-group { | |
| max-width: 100%; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <header> | |
| <div class="logo"> | |
| <i class="fas fa-chart-bar"></i> | |
| <span>TP DP PP 可视化</span> | |
| </div> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link">Built with anycoder</a> | |
| </header> | |
| <h1>TP DP PP 性能可视化分析</h1> | |
| <p class="subtitle">通过交互式图表展示张量并行(TP)、数据并行(DP)和流水线并行(PP)的性能指标</p> | |
| <div class="controls"> | |
| <div class="control-group"> | |
| <h3><i class="fas fa-sliders-h"></i> 参数设置</h3> | |
| <div class="slider-container"> | |
| <label for="tp-slider">张量并行度 (TP)</label> | |
| <input type="range" min="1" max="8" value="4" class="slider" id="tp-slider"> | |
| <div class="slider-value" id="tp-value">4</div> | |
| </div> | |
| <div class="slider-container"> | |
| <label for="dp-slider">数据并行度 (DP)</label> | |
| <input type="range" min="1" max="16" value="8" class="slider" id="dp-slider"> | |
| <div class="slider-value" id="dp-value">8</div> | |
| </div> | |
| <div class="slider-container"> | |
| <label for="pp-slider">流水线并行度 (PP)</label> | |
| <input type="range" min="1" max="8" value="2" class="slider" id="pp-slider"> | |
| <div class="slider-value" id="pp-value">2</div> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <h3><i class="fas fa-cog"></i> 模型配置</h3> | |
| <div class="slider-container"> | |
| <label for="model-size">模型规模 (亿参数)</label> | |
| <input type="range" min="10" max="1000" value="175" class="slider" id="model-size"> | |
| <div class="slider-value" id="model-size-value">175亿</div> | |
| </div> | |
| <div class="slider-container"> | |
| <label for="batch-size">批次大小</label> | |
| <input type="range" min="1" max="128" value="32" class="slider" id="batch-size"> | |
| <div class="slider-value" id="batch-size-value">32</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="metrics"> | |
| <div class="metric-card tp"> | |
| <i class="fas fa-cube"></i> | |
| <h3>张量并行 (TP)</h3> | |
| <div class="metric-value" id="tp-metric">4</div> | |
| <p class="metric-description">将单个张量操作拆分到多个设备上并行计算</p> | |
| </div> | |
| <div class="metric-card dp"> | |
| <i class="fas fa-database"></i> | |
| <h3>数据并行 (DP)</h3> | |
| <div class="metric-value" id="dp-metric">8</div> | |
| <p class="metric-description">将数据拆分到多个设备上,每个设备有完整的模型副本</p> | |
| </div> | |
| <div class="metric-card pp"> | |
| <i class="fas fa-stream"></i> | |
| <h3>流水线并行 (PP)</h3> | |
| <div class="metric-value" id="pp-metric">2</div> | |
| <p class="metric-description">将模型的不同层分配到不同的设备上,形成处理流水线</p> | |
| </div> | |
| </div> | |
| <div class="visualization"> | |
| <div class="chart-container"> | |
| <h3><i class="fas fa-chart-line"></i> 并行效率对比</h3> | |
| <div class="chart" id="efficiency-chart"> | |
| <div class="bar bar-tp" style="height: 85%;" data-value="85">85%</div> | |
| <div class="bar bar-dp" style="height: 92%;" data-value="92">92%</div> | |
| <div class="bar bar-pp" style="height: 78%;" data-value="78">78%</div> | |
| </div> | |
| </div> | |
| <div class="chart-container"> | |
| <h3><i class="fas fa-tachometer-alt"></i> 内存使用情况</h3> | |
| <div class="chart" id="memory-chart"> | |
| <div class="bar bar-tp" style="height: 65%;" data-value="65">65%</div> | |
| <div class="bar bar-dp" style="height: 85%;" data-value="85">85%</div> | |
| <div class="bar bar-pp" style="height: 45%;" data-value="45">45%</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="comparison"> | |
| <h3><i class="fas fa-balance-scale"></i> 综合性能对比</h3> | |
| <div class="comparison-chart"> | |
| <div class="comparison-bar bar-tp" style="height: 75%;">TP</div> | |
| <div class="comparison-bar bar-dp" style="height: 88%;">DP</div> | |
| <div class="comparison-bar bar-pp" style="height: 62%;">PP</div> | |
| </div> | |
| </div> | |
| <footer> | |
| <p>TP DP PP 可视化分析工具 | 使用交互式图表展示并行计算性能指标</p> | |
| </footer> | |
| </div> | |
| <script> | |
| // 获取DOM元素 | |
| const tpSlider = document.getElementById('tp-slider'); | |
| const dpSlider = document.getElementById('dp-slider'); | |
| const ppSlider = document.getElementById('pp-slider'); | |
| const modelSizeSlider = document.getElementById('model-size'); | |
| const batchSizeSlider = document.getElementById('batch-size'); | |
| const tpValue = document.getElementById('tp-value'); | |
| const dpValue = document.getElementById('dp-value'); | |
| const ppValue = document.getElementById('pp-value'); | |
| const modelSizeValue = document.getElementById('model-size-value'); | |
| const batchSizeValue = document.getElementById('batch-size-value'); | |
| const tpMetric = document.getElementById('tp-metric'); | |
| const dpMetric = document.getElementById('dp-metric'); | |
| const ppMetric = document.getElementById('pp-metric'); | |
| const efficiencyBars = document.querySelectorAll('#efficiency-chart .bar'); | |
| const memoryBars = document.querySelectorAll('#memory-chart .bar'); | |
| const comparisonBars = document.querySelectorAll('.comparison-bar'); | |
| // 更新滑块值显示 | |
| function updateSliderValues() { | |
| tpValue.textContent = tpSlider.value; | |
| dpValue.textContent = dpSlider.value; | |
| ppValue.textContent = ppSlider.value; | |
| const modelSize = parseInt(modelSizeSlider.value); | |
| modelSizeValue.textContent = modelSize + '亿'; | |
| batchSizeValue.textContent = batchSizeSlider.value; | |
| // 更新指标卡 | |
| tpMetric.textContent = tpSlider.value; | |
| dpMetric.textContent = dpSlider.value; | |
| ppMetric.textContent = ppSlider.value; | |
| // 更新图表 | |
| updateCharts(); | |
| } | |
| // 更新图表数据 | |
| function updateCharts() { | |
| const tp = parseInt(tpSlider.value); | |
| const dp = parseInt(dpSlider.value); | |
| const pp = parseInt(ppSlider.value); | |
| const modelSize = parseInt(modelSizeSlider.value); | |
| const batchSize = parseInt(batchSizeSlider.value); | |
| // 计算效率百分比(模拟算法) | |
| const tpEfficiency = Math.max(50, 100 - (tp - 1) * 5); | |
| const dpEfficiency = Math.max(60, 100 - (dp - 1) * 1); | |
| const ppEfficiency = Math.max(40, 100 - (pp - 1) * 10); | |
| // 计算内存使用(模拟算法) | |
| const tpMemory = Math.min(95, 30 + tp * 10); | |
| const dpMemory = Math.min(95, 50 + dp * 5); | |
| const ppMemory = Math.min(95, 20 + pp * 15); | |
| // 计算综合性能(模拟算法) | |
| const tpPerformance = Math.max(30, 90 - (tp - 1) * 5); | |
| const dpPerformance = Math.max(40, 95 - (dp - 1) * 1); | |
| const ppPerformance = Math.max(20, 70 - (pp - 1) * 8); | |
| // 更新效率图表 | |
| efficiencyBars[0].style.height = tpEfficiency + '%'; | |
| efficiencyBars[0].textContent = tpEfficiency + '%'; | |
| efficiencyBars[0].setAttribute('data-value', tpEfficiency); | |
| efficiencyBars[1].style.height = dpEfficiency + '%'; | |
| efficiencyBars[1].textContent = dpEfficiency + '%'; | |
| efficiencyBars[1].setAttribute('data-value', dpEfficiency); | |
| efficiencyBars[2].style.height = ppEfficiency + '%'; | |
| efficiencyBars[2].textContent = ppEfficiency + '%'; | |
| efficiencyBars[2].setAttribute('data-value', ppEfficiency); | |
| // 更新内存图表 | |
| memoryBars[0].style.height = tpMemory + '%'; | |
| memoryBars[0].textContent = tpMemory + '%'; | |
| memoryBars[0].setAttribute('data-value', tpMemory); | |
| memoryBars[1].style.height = dpMemory + '%'; | |
| memoryBars[1].textContent = dpMemory + '%'; | |
| memoryBars[1].setAttribute('data-value', dpMemory); | |
| memoryBars[2].style.height = ppMemory + '%'; | |
| memoryBars[2].textContent = ppMemory + '%'; | |
| memoryBars[2].setAttribute('data-value', ppMemory); | |
| // 更新综合性能图表 | |
| comparisonBars[0].style.height = tpPerformance + '%'; | |
| comparisonBars[1].style.height = dpPerformance + '%'; | |
| comparisonBars[2].style.height = ppPerformance + '%'; | |
| } | |
| // 添加事件监听器 | |
| tpSlider.addEventListener('input', updateSliderValues); | |
| dpSlider.addEventListener('input', updateSliderValues); | |
| ppSlider.addEventListener('input', updateSliderValues); | |
| modelSizeSlider.addEventListener('input', updateSliderValues); | |
| batchSizeSlider.addEventListener('input', updateSliderValues); | |
| // 初始化 | |
| updateSliderValues(); | |
| </script> | |
| </body> | |
| </html> |