Files
sanbuphy 0eba9e87e9 fix(eslint): reduce warnings in GitHub Actions deployment
- Disable formatting rules (handled by Prettier)
- Relaxed strict Vue/JS rules for demo code compatibility
- Fix syntax errors in ApiPlayground and VoiceCloningDemo
- Fix duplicate else-if condition in ApiPlayground
- Fix Promise executor async pattern in AutoregressiveAudioDemo
- Add TypeScript file support to ESLint config

Warnings reduced from 295 to 251 problems.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-18 17:38:10 +08:00

448 lines
9.1 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="vit-output-demo">
<div class="pipeline">
<!-- 1. Transformer Output Grid -->
<div class="stage">
<div class="stage-label">
1. Patch Tokens (Shown as Grid) (Patch Token 网格示意)
</div>
<div class="grid-container">
<div
v-for="(item, index) in items"
:key="index"
class="grid-item"
:class="{ active: activeIndex === index }"
@mouseenter="activeIndex = index"
>
<span class="icon">{{ item.icon }}</span>
</div>
</div>
</div>
<div class="arrow-section">
<div class="arrow-line" />
<div class="arrow-text">
Reshape for View: Grid Sequence (重排显示网格序列)
</div>
</div>
<!-- 2. Feature Vector Sequence -->
<div class="stage">
<div class="stage-label">
2. Output Token Sequence (N×D) (输出序列)
</div>
<div class="vector-sequence">
<div
v-for="(item, index) in items"
:key="index"
class="vector-wrapper"
:class="{ active: activeIndex === index }"
@mouseenter="activeIndex = index"
>
<div class="vector-col">
<!-- Simulated vector dimensions -->
<div
class="v-cell"
:style="{ opacity: 0.9, background: item.color }"
/>
<div
class="v-cell"
:style="{ opacity: 0.7, background: item.color }"
/>
<div
class="v-cell"
:style="{ opacity: 0.5, background: item.color }"
/>
<div
class="v-cell"
:style="{ opacity: 0.8, background: item.color }"
/>
<div
class="v-cell"
:style="{ opacity: 0.6, background: item.color }"
/>
</div>
<div class="vector-idx">
{{ index + 1 }}
</div>
</div>
</div>
</div>
</div>
<!-- 3. Semantic Panel -->
<div class="semantic-panel">
<div
v-if="activeIndex !== -1"
class="semantic-content"
>
<div
class="header"
:style="{ borderColor: items[activeIndex].color }"
>
<span class="large-icon">{{ items[activeIndex].icon }}</span>
<div class="title-group">
<span class="title">Token #{{ activeIndex + 1 }}:
{{ items[activeIndex].label }}</span>
<span class="subtitle">Type: {{ items[activeIndex].type }}</span>
</div>
</div>
<div class="desc">
<div class="vector-repr">
<span class="label">Vector Value:</span>
<span
class="code"
:style="{ color: items[activeIndex].color }"
>
[0.{{ (Math.random() * 99).toFixed(0) }}, -0.{{
(Math.random() * 99).toFixed(0)
}}, 1.{{ (Math.random() * 99).toFixed(0) }}, ...]
</span>
</div>
<div class="meaning">
<strong>🤖 What ViT sees (Semantic):</strong>
<p>{{ items[activeIndex].desc }}</p>
</div>
</div>
</div>
<div
v-else
class="placeholder"
>
<span class="hint-icon">👆</span>
<span class="hint-text">悬停在上方方块或向量上查看 ViT 输出的语义特征</span>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const activeIndex = ref(-1)
const items = [
{
icon: '🌲',
label: 'Background',
type: 'Environment',
color: '#4caf50',
desc: 'Recognized as outdoor nature elements (Trees/Greenery). Low relevance to main subject.'
},
{
icon: '🌲',
label: 'Background',
type: 'Environment',
color: '#4caf50',
desc: 'Redundant background info. Contextualizes the scene as "Outdoors".'
},
{
icon: '☁️',
label: 'Sky',
type: 'Environment',
color: '#2196f3',
desc: 'Spatial context: Upper region, open area.'
},
{
icon: '👂',
label: 'Cat Ear',
type: 'Subject Part',
color: '#ff9800',
desc: 'High Importance. Identified as "Feline Feature". Strongly linked to "Cat Face".'
},
{
icon: '😼',
label: 'Cat Face',
type: 'Subject Core',
color: '#ff5722',
desc: 'Global Focus Center. Contains "Eyes", "Whiskers". Aggregates info from surrounding patches.'
},
{
icon: '🌲',
label: 'Background',
type: 'Environment',
color: '#4caf50',
desc: 'Background noise.'
},
{
icon: '🐾',
label: 'Cat Paw',
type: 'Subject Part',
color: '#ff9800',
desc: 'Action component. Suggests "Standing" or "Walking" posture.'
},
{
icon: '🧶',
label: 'Yarn',
type: 'Object',
color: '#e91e63',
desc: 'Interacting Object. Semantically linked to "Play" or "Toy".'
},
{
icon: '🌱',
label: 'Grass',
type: 'Environment',
color: '#8bc34a',
desc: 'Ground context. Confirms "Ground level" view.'
}
]
</script>
<style scoped>
.vit-output-demo {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 12px;
padding: 24px;
font-family:
system-ui,
-apple-system,
sans-serif;
max-width: 700px;
margin: 20px auto;
}
.dark .vit-output-demo {
background: #1e1e20;
border-color: #2d2d30;
color: #e0e0e0;
}
.pipeline {
display: flex;
flex-direction: column;
gap: 16px;
align-items: center;
}
.stage {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.stage-label {
font-size: 12px;
text-transform: uppercase;
color: #868e96;
margin-bottom: 8px;
font-weight: 600;
}
/* Grid Stage */
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 6px;
background: #fff;
padding: 8px;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.dark .grid-container {
background: #252529;
}
.grid-item {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: #f1f3f5;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
font-size: 20px;
}
.dark .grid-item {
background: #343a40;
}
.grid-item:hover,
.grid-item.active {
background: #e7f5ff;
transform: scale(1.1);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.dark .grid-item:hover,
.dark .grid-item.active {
background: #1c7ed6;
}
/* Arrow */
.arrow-section {
display: flex;
align-items: center;
gap: 8px;
color: #adb5bd;
}
.arrow-line {
width: 2px;
height: 20px;
background: #dee2e6;
}
/* Vector Sequence Stage */
.vector-sequence {
display: flex;
gap: 4px;
padding: 10px;
background: #fff;
border-radius: 6px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
overflow-x: auto;
max-width: 100%;
}
.dark .vector-sequence {
background: #252529;
}
.vector-wrapper {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
cursor: pointer;
padding: 4px;
border-radius: 4px;
transition: background 0.2s;
}
.vector-wrapper:hover,
.vector-wrapper.active {
background: rgba(0, 0, 0, 0.05);
}
.dark .vector-wrapper:hover,
.dark .vector-wrapper.active {
background: rgba(255, 255, 255, 0.1);
}
.vector-col {
display: flex;
flex-direction: column;
gap: 1px;
}
.v-cell {
width: 12px;
height: 6px;
border-radius: 1px;
}
.vector-idx {
font-size: 10px;
color: #adb5bd;
}
/* Semantic Panel */
.semantic-panel {
margin-top: 24px;
background: #fff;
border: 1px solid #e9ecef;
border-radius: 6px;
padding: 16px;
min-height: 120px;
display: flex;
align-items: center;
justify-content: center;
}
.dark .semantic-panel {
background: #252529;
border-color: #343a40;
}
.placeholder {
color: #868e96;
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.semantic-content {
width: 100%;
text-align: left;
}
.header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 12px;
padding-bottom: 12px;
border-bottom: 2px solid #eee;
}
.large-icon {
font-size: 32px;
background: #f8f9fa;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
}
.dark .large-icon {
background: #343a40;
}
.title-group {
display: flex;
flex-direction: column;
}
.title {
font-weight: bold;
font-size: 16px;
color: #343a40;
}
.dark .title {
color: #f8f9fa;
}
.subtitle {
font-size: 12px;
color: #868e96;
}
.desc {
font-size: 14px;
color: #495057;
}
.dark .desc {
color: #ced4da;
}
.vector-repr {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
font-family: 'Menlo', monospace;
font-size: 12px;
background: #f1f3f5;
padding: 4px 8px;
border-radius: 4px;
width: fit-content;
}
.dark .vector-repr {
background: #343a40;
}
.label {
color: #868e96;
}
.meaning strong {
display: block;
margin-bottom: 4px;
color: #212529;
}
.dark .meaning strong {
color: #f8f9fa;
}
</style>