From ee3e3bbb247605d1fb440c333a0a962df95d0582 Mon Sep 17 00:00:00 2001 From: abhimazu <mail.abhijeetmazumdar@gmail.com> Date: Wed, 26 Feb 2025 15:14:21 -0500 Subject: [PATCH] Moved model provenance from model zoo to Foundation --- .../Foundation/CurrentFoundationInfo.tsx | 37 +++ src/renderer/components/MainAppPanel.tsx | 4 - .../components/ModelZoo/ModelJourney.tsx | 252 ------------------ src/renderer/components/ModelZoo/ModelZoo.tsx | 8 - 4 files changed, 37 insertions(+), 264 deletions(-) delete mode 100644 src/renderer/components/ModelZoo/ModelJourney.tsx diff --git a/src/renderer/components/Experiment/Foundation/CurrentFoundationInfo.tsx b/src/renderer/components/Experiment/Foundation/CurrentFoundationInfo.tsx index 4d870b32..b167f44a 100644 --- a/src/renderer/components/Experiment/Foundation/CurrentFoundationInfo.tsx +++ b/src/renderer/components/Experiment/Foundation/CurrentFoundationInfo.tsx @@ -64,6 +64,17 @@ export default function CurrentFoundationInfo({ const [huggingfaceData, setHugggingfaceData] = useState({}); const huggingfaceId = experimentInfo?.config?.foundation; + // Sample provenance data – replace with your actual data source. + const provenanceData = [ + { jobId: 3, jobType: 'Train', metadata: { dataset: 'win-wang/Machine_Learning_QA_Collection' }, date: '2024-08-01' }, + { jobId: 8, jobType: 'Evaluation', metadata: { accuracy: 95.5 }, date: '2024-08-02' }, + { jobId: 10, jobType: 'Evaluation', metadata: { accuracy: 95.5}, date: '2024-08-03' }, + { jobId: 11, jobType: 'Train', metadata: { dataset: 'win-wang/Machine_Learning_QA_Collection' }, date: '2024-08-04' }, + { jobId: 15, jobType: 'Evaluation', metadata: { accuracy: 95.5 }, date: '2024-08-05' }, + { jobId: 19, jobType: 'Train', metadata: { dataset: 'win-wang/Machine_Learning_QA_Collection' }, date: '2024-08-06' }, + ]; + + useMemo(() => { // This is a local model if (experimentInfo?.config?.foundation_filename) { @@ -114,6 +125,32 @@ export default function CurrentFoundationInfo({ )} </tbody> </Table> + {/* Model Provenance Table */} + <Box mt={4}> + <Typography level="h6" mb={1}> + Model Provenance + </Typography> + <Table id="model-provenance-table"> + <thead> + <tr> + <th style={{ width: '10%' }}>Job ID</th> + <th style={{ width: '15%' }}>Job Type</th> + <th style={{ width: '55%' }}>Metadata</th> + <th style={{ width: '20%' }}>Date</th> + </tr> + </thead> + <tbody> + {provenanceData.map((row) => ( + <tr key={row.jobId}> + <td style={{ width: '10%' }}>{row.jobId}</td> + <td style={{ width: '15%' }}>{row.jobType}</td> + <td style={{ width: '55%' }}>{JSON.stringify(row.metadata)}</td> + <td style={{ width: '20%' }}>{row.date}</td> + </tr> + ))} + </tbody> + </Table> + </Box> </Box> <Box flex={1}> <Typography level="title-lg" marginTop={1} marginBottom={1}> diff --git a/src/renderer/components/MainAppPanel.tsx b/src/renderer/components/MainAppPanel.tsx index af266562..29c8469c 100644 --- a/src/renderer/components/MainAppPanel.tsx +++ b/src/renderer/components/MainAppPanel.tsx @@ -289,10 +289,6 @@ export default function MainAppPanel({ path="/zoo/store" element={<ModelZoo experimentInfo={experimentInfo} tab="store" />} /> - <Route - path="/zoo/journey" - element={<ModelZoo experimentInfo={experimentInfo} tab="journey" />} - /> <Route path="/data" element={<Data />} /> <Route path="/model-home" diff --git a/src/renderer/components/ModelZoo/ModelJourney.tsx b/src/renderer/components/ModelZoo/ModelJourney.tsx deleted file mode 100644 index a64f7c75..00000000 --- a/src/renderer/components/ModelZoo/ModelJourney.tsx +++ /dev/null @@ -1,252 +0,0 @@ -import React, { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import Box from '@mui/joy/Box'; -import Typography from '@mui/joy/Typography'; -import Tooltip from '@mui/joy/Tooltip'; - -// Sample JSON data representing the model journey -const sampleData = { - models: [ - { - type: 'base_model', - id: 'meta/llama3.1-8B-instruct', - name: 'meta/llama3.1-8B-instruct', - children: [ - { - type: 'fine_tuning_job', - jobId: 1, - metadata: { dataset: 'Dataset A' }, - child: { - type: 'fine_tuned_model', - modelId: 'ft_model_1', - name: 'Fine Tuned Model 1', - children: [ - { - type: 'eval_job', - jobId: 2, - metadata: { metric: 'accuracy', value: 95.5 } - }, - { - type: 'eval_job', - jobId: 3, - metadata: { metric: 'accuracy', value: 96.7 } - }, - { - type: 'fine_tuning_job', - jobId: 6, - metadata: { dataset: 'Dataset B' }, - child: { - type: 'fine_tuned_model', - modelId: 'ft_model_3', - name: 'Fine Tuned Model 3', - children: [] - } - } - ] - } - }, - { - type: 'fine_tuning_job', - jobId: 4, - metadata: { dataset: 'Dataset C' }, - child: { - type: 'fine_tuned_model', - modelId: 'ft_model_2', - name: 'Fine Tuned Model 2', - children: [ - { - type: 'eval_job', - jobId: 5, - metadata: { metric: 'accuracy', value: 97.0 } - } - ] - } - } - ] - } - ] -}; - -// Determine styles based on the node type. -const getNodeStyle = (node) => { - switch (node.type) { - case 'base_model': - return { backgroundColor: 'primary.light', color: 'primary.contrastText', border: '1px solid', borderColor: 'divider' }; - case 'fine_tuned_model': - return { backgroundColor: 'info.light', color: 'info.contrastText', border: '1px solid', borderColor: 'divider' }; - case 'fine_tuning_job': - return { backgroundColor: 'success.light', color: 'success.contrastText', border: '1px solid', borderColor: 'divider' }; - case 'eval_job': - return { backgroundColor: 'warning.light', color: 'warning.contrastText', border: '1px solid', borderColor: 'divider' }; - default: - return {}; - } -}; - -// Return a label based on node type. -const getNodeLabel = (node) => { - switch (node.type) { - case 'base_model': - return node.name; - case 'fine_tuned_model': - return node.name; - case 'fine_tuning_job': - return `Fine Tuning Job (ID: ${node.jobId})`; - case 'eval_job': - return `Evaluation (ID: ${node.jobId})`; - default: - return 'Node'; - } -}; - -// Prepare tooltip content from metadata (if available) -const getTooltipContent = (node) => { - if (node.metadata) { - return Object.entries(node.metadata) - .map(([key, value]) => `${key}: ${value}`) - .join(', '); - } - return node.name || ''; -}; - -// Recursive component that renders a job or model node. -const JourneyNode = ({ node }) => { - const navigate = useNavigate(); - - // Click handling: navigate based on the type. - const handleClick = (e) => { - e.stopPropagation(); - if (node.type === 'fine_tuning_job' || node.type === 'eval_job') { - navigate(`/job/${node.jobId}`); - } else if (node.type === 'base_model' || node.type === 'fine_tuned_model') { - // For models, use either node.id or node.modelId - navigate(`/model/${node.id || node.modelId}`); - } - }; - - return ( - <Box sx={{ ml: 4, mt: 2, position: 'relative' }}> - <Tooltip title={getTooltipContent(node)} arrow placement="right"> - <Box - onClick={handleClick} - sx={{ - display: 'inline-block', - px: 1, - py: 0.5, - borderRadius: '8px', - ...getNodeStyle(node), - position: 'relative', - zIndex: 1, - cursor: 'pointer' - }} - > - <Typography level="body2">{getNodeLabel(node)}</Typography> - </Box> - </Tooltip> - - {/* For a fine tuning job, render its single child (the resulting model) */} - {node.type === 'fine_tuning_job' && node.child && ( - <Box sx={{ display: 'flex', mt: 2 }}> - <Box sx={{ width: 20, position: 'relative' }}> - <Box sx={{ position: 'absolute', left: '50%', top: 0, bottom: 0, borderLeft: '2px solid #ccc' }} /> - </Box> - <Box sx={{ flex: 1, display: 'flex', flexDirection: 'column' }}> - <Box sx={{ display: 'flex', alignItems: 'center', position: 'relative' }}> - <Box sx={{ width: 20, position: 'relative' }}> - <Box sx={{ position: 'absolute', left: '50%', top: '50%', width: 20, borderTop: '2px solid #ccc' }} /> - </Box> - <JourneyNode node={node.child} /> - </Box> - </Box> - </Box> - )} - - {/* For model nodes (base_model or fine_tuned_model) with a children array */} - {(node.type === 'base_model' || node.type === 'fine_tuned_model') && - node.children && - node.children.length > 0 && ( - <Box sx={{ display: 'flex', mt: 2 }}> - <Box sx={{ width: 20, position: 'relative' }}> - <Box sx={{ position: 'absolute', left: '50%', top: 0, bottom: 0, borderLeft: '2px solid #ccc' }} /> - </Box> - <Box sx={{ flex: 1, display: 'flex', flexDirection: 'column' }}> - {node.children.map((child) => ( - <Box key={child.jobId || child.modelId} sx={{ display: 'flex', alignItems: 'center', position: 'relative' }}> - <Box sx={{ width: 20, position: 'relative' }}> - <Box sx={{ position: 'absolute', left: '50%', top: '50%', width: 20, borderTop: '2px solid #ccc' }} /> - </Box> - <JourneyNode node={child} /> - </Box> - ))} - </Box> - </Box> - )} - </Box> - ); -}; - -// The base model container is minimized by default and expands when clicked. -const BaseModelBox = ({ model }) => { - const [expanded, setExpanded] = useState(false); - - // Toggle expansion on header click. - const handleHeaderClick = (e) => { - e.stopPropagation(); - setExpanded(!expanded); - }; - - return ( - <Box - sx={{ - border: '1px solid', - borderColor: 'divider', - borderRadius: 2, - p: 2, - mb: 4, - position: 'relative', - cursor: 'pointer' - }} - onClick={handleHeaderClick} - > - {/* Base model header (always visible) */} - <Tooltip title={`Base Model: ${model.name}`} arrow placement="top"> - <Box - sx={{ - position: 'absolute', - top: 8, - left: 8, - borderRadius: '8px', - px: 1, - py: 0.5, - backgroundColor: 'primary.light', - border: '1px solid', - borderColor: 'divider' - }} - > - <Typography level="body2">{model.name}</Typography> - </Box> - </Tooltip> - {/* Expanded content shows the journey (child nodes) */} - {expanded && ( - <Box sx={{ mt: 4 }}> - {model.children && - model.children.map((child) => ( - <JourneyNode key={child.jobId || child.modelId} node={child} /> - ))} - </Box> - )} - </Box> - ); -}; - -const ModelJourney = () => { - return ( - <Box sx={{ p: 2 }}> - {sampleData.models.map((model) => ( - <BaseModelBox key={model.id} model={model} /> - ))} - </Box> - ); -}; - -export default ModelJourney; diff --git a/src/renderer/components/ModelZoo/ModelZoo.tsx b/src/renderer/components/ModelZoo/ModelZoo.tsx index f73aa36a..0aaa44e0 100644 --- a/src/renderer/components/ModelZoo/ModelZoo.tsx +++ b/src/renderer/components/ModelZoo/ModelZoo.tsx @@ -5,7 +5,6 @@ import { StoreIcon } from 'lucide-react'; import { Tab, TabList, TabPanel, Tabs } from '@mui/joy'; import ModelStore from './ModelStore'; import LocalModels from './LocalModels'; -import ModelJourney from './ModelJourney'; import { useNavigate } from 'react-router-dom'; export default function ModelZoo({ experimentInfo, tab = 'store' }) { @@ -42,7 +41,6 @@ export default function ModelZoo({ experimentInfo, tab = 'store' }) { <StoreIcon color="grey" /> Model Store </Tab> - <Tab value="journey">Model Journey</Tab> </TabList> <TabPanel value="local" @@ -65,12 +63,6 @@ export default function ModelZoo({ experimentInfo, tab = 'store' }) { sx={{ p: 0, py: 1, height: '100%', overflow: 'hidden' }} > <ModelStore /> - </TabPanel> - <TabPanel - value="journey" - sx={{ p: 0, py: 1, height: '100%', overflow: 'hidden' }} - > - <ModelJourney /> </TabPanel> </Tabs> </Sheet> -- GitLab