Spaces:
Running
Running
File size: 3,947 Bytes
145a107 0897191 145a107 0897191 145a107 0897191 145a107 e122263 145a107 e122263 145a107 e122263 145a107 e122263 145a107 e122263 145a107 e122263 145a107 e122263 145a107 e122263 145a107 e122263 145a107 e122263 145a107 e122263 145a107 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
<script lang="ts">
let { energyWh, energyWhSim, durationSeconds } = $props();
let showJoules = $state(false);
let showTooltip = $state(false);
const isEstimated = $derived(!(typeof energyWh === 'number' && energyWh !== 0));
const energyToDisplay = $derived(isEstimated ? energyWhSim : energyWh);
function convertToJoules(wh: number): number {
return wh * 3600;
}
let equivalentIndex = $state(0);
const equivalents = [
(wh: number) => `≈ ${((wh / 19) * 100).toFixed(2)}% of a phone charge (19Wh)`,
(wh: number) => `≈ ${(wh / 0.04).toFixed(2)} minutes of LED bulb (10W)`, // 0.04Wh/min
(wh: number) => `≈ ${(wh / 1.5).toFixed(2)} seconds of microwave (1000W)`,
(wh: number) => `≈ ${(wh / 0.2).toFixed(2)} pedal strokes on an e-bike (200W)`,
(wh: number) => `≈ ${(wh / 12).toFixed(2)} seconds of toaster use (1kW)`
];
function cycleEquivalent() {
equivalentIndex = (equivalentIndex + 1) % equivalents.length;
}
</script>
<style>
.energy-box {
transition: transform 0.2s ease;
cursor: pointer;
position: relative;
}
.energy-box:hover {
transform: scale(1.05);
}
.tooltip {
position: absolute;
top: 100%; /* Positionne au-dessus de l’élément parent */
margin-bottom: 0.5rem; /* Équivalent de mb-2 */
left: 50%;
transform: translateX(-50%);
background-color: #f3f4f6; /* bg-gray-200 */
color: #1f2937; /* text-gray-800 */
font-size: 0.75rem; /* text-xs */
padding: 0.5rem 0.75rem; /* px-3 py-2 */
border-radius: 0.25rem; /* rounded */
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -4px rgba(0, 0, 0, 0.1); /* shadow-lg */
z-index: 10;
width: 16rem; /* w-64 */
text-align: center;
}
.info-button {
transition: transform 0.2s ease;
cursor: pointer;
position: relative;
}
.info-button:hover {
transform: scale(1.2);
}
</style>
{#if durationSeconds || energyToDisplay}
<div class="mt-2 flex gap-2 items-center relative">
<!-- Energy Box -->
{#if energyToDisplay}
<div
class="text-xs text-gray-600 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 px-3 py-1 rounded w-fit energy-box"
on:click={() => (showJoules = !showJoules)}
>
Energy:
{#if showJoules}
{convertToJoules(energyToDisplay).toFixed(2)} J {isEstimated ? "(estimated)" : ""}
{:else}
{energyToDisplay.toFixed(4)} Wh {isEstimated ? "(estimated)" : ""}
{/if}
</div>
{/if}
<!-- Equivalent -->
<div
class="text-xs text-gray-600 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 px-3 py-1 rounded w-fit cursor-pointer transform hover:scale-105 transition duration-150 ease-in-out"
on:click={cycleEquivalent}
>
{equivalents[equivalentIndex](energyToDisplay)}
</div>
<!-- Duration -->
{#if durationSeconds}
<div
class="text-xs text-gray-600 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 px-3 py-1 rounded w-fit"
>
Duration: {durationSeconds.toFixed(3)} sec
</div>
{/if}
<!-- Info button -->
<div
class="relative"
on:mouseover={() => (showTooltip = true)}
on:mouseleave={() => (showTooltip = false)}>
<button
class="text-xs text-gray-600 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded-full info-button">
ⓘ
</button>
<!-- Tooltip -->
{#if showTooltip}
<div class="tooltip">
{#if isEstimated}
Estimated energy consumption based on the average GPU power and inference duration for this message. Use Qwen/Qwen/Qwen2.5-VL-7B-Instruct model for exact results.
{:else}
Energy consumption measured directly on the GPU during inference for this message.
{/if}
</div>
{/if}
</div>
</div>
{/if}
|