Spaces:
Sleeping
Sleeping
| <html lang="ko"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>νκ΅μ΄ λ¨μ΄ μλ―Έ λ€νΈμν¬ μκ°ν</title> | |
| <!-- Plotly.js --> | |
| <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> | |
| <!-- Bootstrap CSS --> | |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"> | |
| <style> | |
| body { | |
| font-family: 'Malgun Gothic', 'Apple Gothic', 'NanumGothic', sans-serif; | |
| padding: 20px; | |
| background-color: #f8f9fa; | |
| } | |
| #graphContainer { | |
| height: 80vh; | |
| width: 100%; | |
| border-radius: 8px; | |
| background-color: #fff; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| margin-bottom: 20px; | |
| } | |
| .controls-container { | |
| background-color: #fff; | |
| padding: 20px; | |
| border-radius: 8px; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| margin-bottom: 20px; | |
| } | |
| .spinner { | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| z-index: 1000; | |
| } | |
| .info-section { | |
| margin-top: 20px; | |
| background-color: #fff; | |
| padding: 20px; | |
| border-radius: 8px; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| } | |
| h1, h3 { | |
| color: #343a40; | |
| } | |
| .btn-primary { | |
| background-color: #5a67d8; | |
| border-color: #5a67d8; | |
| } | |
| .btn-primary:hover { | |
| background-color: #4c51bf; | |
| border-color: #4c51bf; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="row mb-4"> | |
| <div class="col-12"> | |
| <h1 class="text-center my-4">νκ΅μ΄ λ¨μ΄ μλ―Έ λ€νΈμν¬ μκ°ν</h1> | |
| <div class="alert alert-info" role="alert"> | |
| μ΄ λꡬλ νκ΅μ΄ λ¨μ΄λ€ κ°μ μλ―Έμ κ΄κ³λ₯Ό 3D 곡κ°μμ μκ°νν©λλ€. BGE-M3 λ€κ΅μ΄ μλ² λ© λͺ¨λΈμ μ¬μ©νμ¬ λ¨μ΄ κ° μλ―Έμ μ μ¬μ±μ λΆμν©λλ€. | |
| </div> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div class="col-md-3"> | |
| <div class="controls-container"> | |
| <h3>μ€μ </h3> | |
| <div class="mb-3"> | |
| <label for="thresholdSlider" class="form-label">μ μ¬λ μκ³κ° ({{ threshold }})</label> | |
| <input type="range" class="form-range" id="thresholdSlider" min="0.1" max="0.9" step="0.05" v-model="threshold"> | |
| <div class="form-text">λμ κ° = λ μ격ν μ°κ²° κΈ°μ€ (μ μ μ£μ§)</div> | |
| </div> | |
| <div class="d-grid gap-2"> | |
| <button class="btn btn-primary" @click="generateGraph" :disabled="isLoading"> | |
| κ·Έλν μμ± | |
| </button> | |
| </div> | |
| <div class="info-section"> | |
| <h3>λ°μ΄ν° μ 보</h3> | |
| <div v-if="dataInfo"> | |
| <p><strong>λ¨μ΄ μ:</strong> {{ dataInfo.wordCount }}</p> | |
| <p><strong>μν λ¨μ΄:</strong></p> | |
| <div class="text-muted">{{ dataInfo.sampleWords.join(', ') }}</div> | |
| </div> | |
| <div v-else> | |
| <p class="text-muted">λ°μ΄ν° μ 보λ₯Ό λ‘λ μ€μ λλ€...</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="col-md-9"> | |
| <div id="graphContainer" style="position: relative;"> | |
| <div class="spinner" v-if="isLoading"> | |
| <div class="spinner-border text-primary" role="status"> | |
| <span class="visually-hidden">λ‘λ© μ€...</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="alert alert-secondary"> | |
| <h5>μ‘°μ λ°©λ²:</h5> | |
| <ul> | |
| <li>λ§μ°μ€ ν : νλ/μΆμ</li> | |
| <li>λ§μ°μ€ λλκ·Έ: νμ </li> | |
| <li>λ§μ°μ€ μ€λ₯Έμͺ½ λ²νΌ λλκ·Έ: μ΄λ</li> | |
| <li>λ¨μ΄μ λ§μ°μ€ μ€λ²: μμΈ μ 보 νμΈ</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="row mt-4"> | |
| <div class="col-12"> | |
| <div class="card"> | |
| <div class="card-body"> | |
| <h3 class="card-title">μ΄ μκ°νμ λν΄</h3> | |
| <p class="card-text"> | |
| μ΄ λꡬλ λ€μκ³Ό κ°μ κΈ°μ μ μ¬μ©νμ¬ νκ΅μ΄ λ¨μ΄ λ€νΈμν¬λ₯Ό μκ°νν©λλ€: | |
| </p> | |
| <ul> | |
| <li><strong>BAAI/bge-m3 μλ² λ©:</strong> λ€μν μΈμ΄μ μ΅μ νλ μ΅μ μλ² λ© λͺ¨λΈλ‘, νκ΅μ΄μμλ μ°μν μ±λ₯μ 보μ λλ€.</li> | |
| <li><strong>t-SNE μ°¨μ μΆμ:</strong> 볡μ‘ν κ³ μ°¨μ 벑ν°λ₯Ό 3D 곡κ°μ ν¬μνμ¬ μλ―Έμ κ΄κ³λ₯Ό μκ°νν©λλ€.</li> | |
| <li><strong>μ½μ¬μΈ μ μ¬λ:</strong> λ¨μ΄ λ²‘ν° κ° κ°λλ₯Ό κΈ°λ°μΌλ‘ μλ―Έμ μ μ¬μ±μ μΈ‘μ ν©λλ€.</li> | |
| <li><strong>Plotly μκ°ν:</strong> μΈν°λν°λΈν 3D μκ°νλ₯Ό μ 곡ν©λλ€.</li> | |
| </ul> | |
| <p class="card-text"> | |
| κ° λ¨μ΄λ 3D 곡κ°μ μ μΌλ‘ νμλλ©°, μ μ¬λκ° λμ λ¨μ΄λ€μ μ°κ²°μ (μ£μ§)μΌλ‘ μ°κ²°λ©λλ€. μμμ zμΆ κ°μ λ°λΌ λ€λ₯΄κ² νμλ©λλ€. | |
| </p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Vue.js --> | |
| <script src="https://cdn.jsdelivr.net/npm/vue@3.2.36/dist/vue.global.prod.js"></script> | |
| <!-- Axios --> | |
| <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> | |
| <script> | |
| const app = Vue.createApp({ | |
| data() { | |
| return { | |
| threshold: 0.7, | |
| isLoading: false, | |
| dataInfo: null, | |
| errorMessage: '' | |
| } | |
| }, | |
| mounted() { | |
| this.loadDataInfo(); | |
| this.generateGraph(); | |
| }, | |
| methods: { | |
| loadDataInfo() { | |
| axios.get('/data-info') | |
| .then(response => { | |
| this.dataInfo = response.data; | |
| }) | |
| .catch(error => { | |
| console.error('λ°μ΄ν° μ 보 λ‘λ μ€λ₯:', error); | |
| }); | |
| }, | |
| generateGraph() { | |
| this.isLoading = true; | |
| this.errorMessage = ''; | |
| axios.post('/generate-graph', { | |
| threshold: this.threshold, | |
| use_default_data: true | |
| }) | |
| .then(response => { | |
| const graphData = response.data; | |
| Plotly.newPlot('graphContainer', JSON.parse(graphData)); | |
| this.isLoading = false; | |
| }) | |
| .catch(error => { | |
| console.error('κ·Έλν μμ± μ€λ₯:', error); | |
| this.errorMessage = 'κ·Έλν μμ± μ€ μ€λ₯κ° λ°μνμ΅λλ€.'; | |
| this.isLoading = false; | |
| }); | |
| } | |
| } | |
| }); | |
| app.mount('.container'); | |
| </script> | |
| </body> | |
| </html> | |