Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Toggle graphs in the training board olena #825

Merged
merged 6 commits into from
Dec 6, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions webapp/src/components/containers/DropdownCard.vue
Original file line number Diff line number Diff line change
@@ -16,22 +16,37 @@
</template>
</IconCardHeader>

<div v-show="opened" class="text-sm text-slate-500 dark:text-slate-300 p-8 border-t">
<div
v-show="opened"
class="text-sm text-slate-500 dark:text-slate-300 p-8 border-t"
>
<slot />
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { ref, watch } from "vue";
import UpArrow from "@/assets/svg/UpArrow.vue";
import DownArrow from "@/assets/svg/DownArrow.vue";
import IconCardHeader from "./IconCardHeader.vue";
const props = withDefaults(
defineProps<{
initiallyOpen?: boolean;
}>(),
{ initiallyOpen: true },
);
const opened = ref(true);
watch(props, ({ initiallyOpen }) => {
opened.value = initiallyOpen;
});
function toggle() {
opened.value = !opened.value;
}
253 changes: 124 additions & 129 deletions webapp/src/components/training/TrainingInformation.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
<template>
<div class="space-y-4 md:space-y-8">
<!-- Fancy training statistics -->
<div class="flex flex-wrap justify-center 2xl:justify-between gap-4 md:gap-8">
<div
class="flex flex-wrap justify-center 2xl:justify-between gap-4 md:gap-8"
>
<!-- Hide the communication rounds when training alone -->
<IconCardSmall
v-if="!isTrainingAlone"
v-tippy="{
content: 'The number of times the model has been updated with models shared by collaborators. No data is shared.',
placement: 'top'
}"
header="Collaborative model sharing"
:text="`${rounds.size}`"
class="w-72 shrink-0 hover:cursor-pointer"
v-if="!isTrainingAlone"
v-tippy="{
content:
'The number of times the model has been updated with models shared by collaborators. No data is shared.',
placement: 'top',
}"
header="Collaborative model sharing"
:text="`${rounds.size}`"
class="w-72 shrink-0 hover:cursor-pointer"
>
<ModelExchangeIcon custom-class="text-gray-300 w-9 h-9" />
</IconCardSmall>
<IconCardSmall
v-tippy="{
content: 'The number of complete passes through the training dataset.',
placement: 'top'
content:
'The number of complete passes through the training dataset.',
placement: 'top',
}"
header="epochs"
:text="`${allEpochs.size} / ${numberOfEpochs}`"
@@ -28,8 +32,9 @@
</IconCardSmall>
<IconCardSmall
v-tippy="{
content: 'The number of times the model has been updated during the current epoch.',
placement: 'top'
content:
'The number of times the model has been updated during the current epoch.',
placement: 'top',
}"
header="current batch"
:text="`${batchesCount}`"
@@ -40,8 +45,9 @@

<IconCardSmall
v-tippy="{
content: 'Number of collaborators concurrently training a model and sharing model updates.',
placement: 'top'
content:
'Number of collaborators concurrently training a model and sharing model updates.',
placement: 'top',
}"
header="number of participants"
:text="`${participants.current}`"
@@ -52,127 +58,105 @@
</div>

<!-- Training and validation loss charts -->
<div
class="flex flex-col md:grid gap-4 md:gap-8 md:grid-cols-2"
>
<!-- Training loss users chart -->
<IconCard>
<template #title> Training Loss of the Model </template>

<span class="text-2xl font-medium text-slate-500 dark:text-slate-300">
{{ (lastEpoch?.training.loss ?? 0).toFixed(2) }}
</span>
<span class="text-sm font-medium text-slate-500 dark:text-slate-400">
training loss
</span>
<DropdownCard :initiallyOpen @click="toggleAdvancedInfo">
<template #title> Advanced information </template>
<div class="flex flex-col md:grid gap-4 md:gap-8 md:grid-cols-2">
<!-- Training loss users chart -->
<IconCard>
<template #title> Training Loss of the Model </template>

<ApexChart
width="100%"
height="200"
type="area"
:options="lossChartsOptions"
:series="[{ name: 'Training loss', data: lossSeries.training }]"
/>
</IconCard>
<span class="text-2xl font-medium text-slate-500 dark:text-slate-300">
{{ (lastEpoch?.training.loss ?? 0).toFixed(2) }}
</span>
<span class="text-sm font-medium text-slate-500 dark:text-slate-400">
training loss
</span>

<!-- Training Accuracy users chart -->
<IconCard>
<template #title> Training Accuracy of the Model </template>
<ApexChart
width="100%"
height="200"
type="area"
:options="lossChartsOptions"
:series="[{ name: 'Training loss', data: lossSeries.training }]"
/>
</IconCard>

<span class="text-2xl font-medium text-slate-500 dark:text-slate-300">
{{ percent(lastEpoch?.training.accuracy ?? 0) }}
</span>
<span class="text-sm font-medium text-slate-500 dark:text-slate-400">
% of training accuracy
</span>
<!-- Training Accuracy users chart -->
<IconCard>
<template #title> Training Accuracy of the Model </template>

<ApexChart
width="100%"
height="200"
type="area"
:options="accuracyChartsOptions"
:series="[
{ name: 'Training accuracy', data: accuracySeries.training },
]"
/>
</IconCard>
</div>
<span class="text-2xl font-medium text-slate-500 dark:text-slate-300">
{{ percent(lastEpoch?.training.accuracy ?? 0) }}
</span>
<span class="text-sm font-medium text-slate-500 dark:text-slate-400">
% of training accuracy
</span>

<!-- Training and validation accuracy charts -->
<div
v-if="hasValidationData"
class="flex flex-col md:grid gap-4 md:gap-8 md:grid-cols-2"
>
<!-- Validation Loss users chart -->
<IconCard>
<template #title> Validation Loss of the Model </template>
<ApexChart
width="100%"
height="200"
type="area"
:options="accuracyChartsOptions"
:series="[
{ name: 'Training accuracy', data: accuracySeries.training },
]"
/>
</IconCard>
</div>

<span class="text-2xl font-medium text-slate-500 dark:text-slate-300">
{{ (lastEpoch?.validation?.loss ?? 0).toFixed(2) }}
</span>
<span class="text-sm font-medium text-slate-500 dark:text-slate-400">
validation loss
</span>
<!-- Training and validation accuracy charts -->
<div
v-if="hasValidationData"
class="flex flex-col md:grid gap-4 md:gap-8 md:grid-cols-2"
>
<!-- Validation Loss users chart -->
<IconCard>
<template #title> Validation Loss of the Model </template>

<ApexChart
width="100%"
height="200"
type="area"
:options="lossChartsOptions"
:series="[{ name: 'Validation loss', data: lossSeries.validation }]"
/>
</IconCard>
<!-- Validation Accuracy users chart -->
<IconCard>
<template #title> Validation Accuracy of the Model </template>
<span class="text-2xl font-medium text-slate-500 dark:text-slate-300">
{{ (lastEpoch?.validation?.loss ?? 0).toFixed(2) }}
</span>
<span class="text-sm font-medium text-slate-500 dark:text-slate-400">
validation loss
</span>

<span class="text-2xl font-medium text-slate-500 dark:text-slate-300">
{{ percent(lastEpoch?.validation?.accuracy ?? 0) }}
</span>
<span class="text-sm font-medium text-slate-500 dark:text-slate-400">
% of validation accuracy
</span>
<ApexChart
width="100%"
height="200"
type="area"
:options="lossChartsOptions"
:series="[{ name: 'Validation loss', data: lossSeries.validation }]"
/>
</IconCard>
<!-- Validation Accuracy users chart -->
<IconCard>
<template #title> Validation Accuracy of the Model </template>

<ApexChart
width="100%"
height="200"
type="area"
:options="accuracyChartsOptions"
:series="[
{ name: 'Validation accuracy', data: accuracySeries.validation },
]"
/>
</IconCard>
</div>
<span class="text-2xl font-medium text-slate-500 dark:text-slate-300">
{{ percent(lastEpoch?.validation?.accuracy ?? 0) }}
</span>
<span class="text-sm font-medium text-slate-500 dark:text-slate-400">
% of validation accuracy
</span>

<IconCard>
<template #title> Training Logs </template>
<template #icon> <Contact /> </template>

<!-- Scrollable training logs -->
<div id="mapHeader" class="max-h-80 overflow-y-auto">
<ul class="grid grid-cols-1">
<li
v-for="(message, index) in props.messages"
:key="index"
class="border-slate-400"
>
<span
style="white-space: pre-line"
class="text-sm text-slate-500 dark:text-slate-400"
>
{{ message }}
</span>
</li>
</ul>
<ApexChart
width="100%"
height="200"
type="area"
:options="accuracyChartsOptions"
:series="[
{ name: 'Validation accuracy', data: accuracySeries.validation },
]"
/>
</IconCard>
</div>
</IconCard>
</DropdownCard>
</div>
</template>

<script setup lang="ts">
import { List } from "immutable";
import { computed } from "vue";
import { computed, ref } from "vue";
import ApexChart from "vue3-apexcharts";
import type { BatchLogs, EpochLogs, RoundLogs } from "@epfml/discojs";
@@ -183,7 +167,11 @@ import Timer from "@/assets/svg/Timer.vue";
import ModelExchangeIcon from "@/assets/svg/ModelExchangeIcon.vue";
import ModelUpdateIcon from "@/assets/svg/ModelUpdateIcon.vue";
import PeopleIcon from "@/assets/svg/PeopleIcon.vue";
import Contact from "@/assets/svg/Contact.vue";
import DropdownCard from "../containers/DropdownCard.vue";
const initiallyOpen = ref(
localStorage.getItem("initiallyOpen") === "true" ? true : false,
);
const props = defineProps<{
rounds: List<RoundLogs>;
@@ -192,8 +180,8 @@ const props = defineProps<{
batchesOfEpoch: List<BatchLogs>;
hasValidationData: boolean; // TODO infer from logs
messages: List<string>; // TODO why do we want messages?
isTrainingAlone: boolean // Should be set to True if using the training scheme 'local'
isTraining: boolean // Is the user currently training a model
isTrainingAlone: boolean; // Should be set to True if using the training scheme 'local'
isTraining: boolean; // Is the user currently training a model
}>();
const participants = computed(() => ({
@@ -204,7 +192,7 @@ const participants = computed(() => ({
average:
props.rounds.size > 0
? props.rounds.reduce((acc, round) => acc + round.participants, 0) /
props.rounds.size
props.rounds.size
: 0,
}));
@@ -312,13 +300,13 @@ const commonChartsOptions = {
},
},
tooltip: {
theme: darkMode ? 'dark' : 'light',
theme: darkMode ? "dark" : "light",
style: {
fontSize: '12px',
fontSize: "12px",
fontFamily: undefined,
colors: darkMode ? '#ffffff' : '#000000',
colors: darkMode ? "#ffffff" : "#000000",
},
}
},
};
const accuracyChartsOptions = {
@@ -359,4 +347,11 @@ const lossChartsOptions = computed(() => {
function percent(n: number): string {
return (n * 100).toFixed(2);
}
</script>
// Function to toggle the advanced information
function toggleAdvancedInfo(): void {
const newOpen = initiallyOpen.value === false ? true : false;
localStorage.setItem("initiallyOpen", newOpen + "");
initiallyOpen.value = newOpen;
}
</script>

This file was deleted.