Skip to content

Commit

Permalink
Add an 'Import from hugging face' modal
Browse files Browse the repository at this point in the history
  • Loading branch information
agatha197 committed Jul 5, 2024
1 parent 1a742c0 commit 7fd4eff
Show file tree
Hide file tree
Showing 23 changed files with 368 additions and 33 deletions.
2 changes: 1 addition & 1 deletion config.toml.sample
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ isDirectorySizeVisible = true # If false, directory size in folder exp
maxCountForPreopenPorts = 10 # The maximum allowed number of preopen ports. If you set this option to 0, the feature of preopen ports is disabled.
allowCustomResourceAllocation = true # If true, display the custom allocation on the session launcher.
eduAppNamePrefix = "" # The prefix of edu applauncher's app name. If the app name starts with this prefix, split it by '-' and use the tail as the name of image.
supportModelStore = false # Enable model store feature. (From Backend.AI 24.03)
supportModelStore = false # Enable model store feature. (From Backend.AI 24.03)

[wsproxy]
proxyURL = "[Proxy URL]"
Expand Down
126 changes: 126 additions & 0 deletions react/src/components/ImportFromHuggingFaceModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import BAIModal, { BAIModalProps } from './BAIModal';
import Flex from './Flex';
import { FilterOutlined } from '@ant-design/icons';
import { useToggle } from 'ahooks';
import {
Button,
Card,
Form,
FormInstance,
Input,
InputNumber,
Switch,
theme,
Typography,
} from 'antd';
import Markdown from 'markdown-to-jsx';
import React, { useRef } from 'react';
import { useTranslation } from 'react-i18next';

type Service = {
url: string;
inference_engine_version?: string;
replica_number?: number;
};

interface ImportFromHuggingFaceModalProps extends BAIModalProps {
onRequestClose: () => void;
}

const ImportFromHuggingFaceModal: React.FC<ImportFromHuggingFaceModalProps> = ({
onRequestClose,
...baiModalProps
}) => {
const { t } = useTranslation();
const { token } = theme.useToken();
const formRef = useRef<FormInstance<Service>>(null);
const [isStartService, { toggle: toggleStartService }] = useToggle(false);

const handleOnClick = () => {
formRef.current
?.validateFields()
.then((values) => {
// TODO: Implement import from Hugging Face
onRequestClose();
})
.catch(() => {});
};

return (
<BAIModal
title={t('data.modelStore.ImportFromHuggingFace')}
centered
footer={
<Button type="primary" htmlType="submit" onClick={handleOnClick}>
{isStartService
? t('data.modelStore.ImportAndStartService')
: t('data.modelStore.Import')}
</Button>
}
onCancel={onRequestClose}
{...baiModalProps}
>
<Form
ref={formRef}
preserve={false}
layout="vertical"
requiredMark="optional"
>
<Form.Item name="url" rules={[{ required: true }]}>
<Input placeholder={t('data.modelStore.huggingFaceUrlPlaceholder')} />
</Form.Item>
<Card
size="small"
title={
<Flex direction="row" gap="xs">
<FilterOutlined />
README.md
</Flex>
}
styles={{
body: {
padding: token.paddingLG,
overflow: 'auto',
minHeight: 200,
maxHeight: token.screenXS,
},
}}
>
<Markdown>{''}</Markdown>
</Card>
<Flex
gap={'xs'}
style={{ marginTop: token.marginLG, marginBottom: token.marginLG }}
>
<Switch
checked={isStartService}
onChange={(e) => {
toggleStartService();
}}
/>
<Typography.Text>{t('data.modelStore.StartService')}</Typography.Text>
</Flex>
{isStartService ? (
<Card>
<Form.Item
name="inference_engine_version"
label={t('data.modelStore.InferenceEngineVersion')}
rules={[{ required: isStartService }]}
>
<Input />
</Form.Item>
<Form.Item
name="replica_number"
label={t('data.modelStore.ReplicaNumber')}
rules={[{ required: isStartService }]}
>
<InputNumber style={{ width: '100%' }} />
</Form.Item>
</Card>
) : null}
</Form>
</BAIModal>
);
};

export default ImportFromHuggingFaceModal;
51 changes: 40 additions & 11 deletions react/src/pages/VFolderListPage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import Flex from '../components/Flex';
import ImportFromHuggingFaceModal from '../components/ImportFromHuggingFaceModal';
import { filterEmptyItem } from '../helper';
import { useSuspendedBackendaiClient, useUpdatableState } from '../hooks';
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
import {
DeleteOutlined,
ImportOutlined,
PlusOutlined,
} from '@ant-design/icons';
import { useToggle } from 'ahooks';
import { Alert, Button, Card, Skeleton, theme } from 'antd';
import _ from 'lodash';
import React, { Suspense, useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { StringParam, useQueryParam, withDefault } from 'use-query-params';
Expand Down Expand Up @@ -37,6 +44,10 @@ const VFolderListPage: React.FC<VFolderListPageProps> = (props) => {
const baiClient = useSuspendedBackendaiClient();
const [fetchKey, updateFetchKey] = useUpdatableState('first');
const dataViewRef = useRef(null);
const [
isVisibleImportFromHuggingFaceModal,
{ toggle: toggleImportFromHuggingFaceModal },
] = useToggle(false);

const { token } = theme.useToken();

Expand Down Expand Up @@ -102,16 +113,28 @@ const VFolderListPage: React.FC<VFolderListPageProps> = (props) => {
},
}}
tabBarExtraContent={
<Button
type="primary"
icon={<PlusOutlined />}
onClick={() => {
// @ts-ignore
dataViewRef.current?.openAddFolderDialog();
}}
>
{t('data.Add')}
</Button>
<Flex gap="xs">
{_.includes(['model', 'model-store'], curTabKey) ? (
<Button
icon={<ImportOutlined />}
onClick={toggleImportFromHuggingFaceModal}
// Remove this line to test
style={{ display: 'none' }}
>
{t('data.modelStore.ImportFromHuggingFace')}
</Button>
) : null}
<Button
type="primary"
icon={<PlusOutlined />}
onClick={() => {
// @ts-ignore
dataViewRef.current?.openAddFolderDialog();
}}
>
{t('data.Add')}
</Button>
</Flex>
}
>
{tabBannerText ? (
Expand All @@ -127,6 +150,12 @@ const VFolderListPage: React.FC<VFolderListPageProps> = (props) => {
{/* @ts-ignore */}
<backend-ai-data-view ref={dataViewRef} active _activeTab={curTabKey} />
</Card>
<ImportFromHuggingFaceModal
open={isVisibleImportFromHuggingFaceModal}
onRequestClose={() => {
toggleImportFromHuggingFaceModal();
}}
/>
</Flex>
);
};
Expand Down
11 changes: 10 additions & 1 deletion resources/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,16 @@
"Add": "hinzufügen",
"CloningIsOnlyPossibleSameHost": "Derzeit ist das Klonen nur auf demselben Host möglich.",
"userQuotaScopeId": "Quota Scope ID",
"NewFolderName": "Neuer Ordnername"
"NewFolderName": "Neuer Ordnername",
"modelStore": {
"ImportFromHuggingFace": "Aus Hugging Face importieren",
"Import": "Importieren",
"StartService": "Dienst starten",
"InferenceEngineVersion": "Version der Inferenz-Engine",
"ReplicaNumber": "Replikatnummer",
"ImportAndStartService": "Dienst importieren und starten",
"huggingFaceUrlPlaceholder": "Geben Sie die URL Hugging Face ein"
}
},
"dialog": {
"warning": {
Expand Down
11 changes: 10 additions & 1 deletion resources/i18n/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,16 @@
"Add": "Προσθέστε",
"CloningIsOnlyPossibleSameHost": "Προς το παρόν, η κλωνοποίηση είναι δυνατή μόνο στον ίδιο κεντρικό υπολογιστή.",
"userQuotaScopeId": "Quota Scope ID",
"NewFolderName": "Νέο όνομα φακέλου"
"NewFolderName": "Νέο όνομα φακέλου",
"modelStore": {
"ImportFromHuggingFace": "Εισαγωγή από το Hugging Face",
"Import": "Εισαγωγή",
"StartService": "Ξεκινήστε την υπηρεσία",
"InferenceEngineVersion": "Έκδοση Inference Engine",
"ReplicaNumber": "Αριθμός αντιγράφου",
"ImportAndStartService": "Εισαγωγή και έναρξη υπηρεσίας",
"huggingFaceUrlPlaceholder": "Εισαγάγετε τη διεύθυνση URL Hugging Face."
}
},
"dialog": {
"warning": {
Expand Down
11 changes: 10 additions & 1 deletion resources/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,16 @@
"Add": "Add",
"CloningIsOnlyPossibleSameHost": "Currently, cloning is only possible on the same host.",
"userQuotaScopeId": "Quota Scope ID",
"NewFolderName": "New folder name"
"NewFolderName": "New folder name",
"modelStore": {
"ImportFromHuggingFace": "Import From Hugging Face",
"Import": "Import",
"StartService": "Start Service",
"InferenceEngineVersion": "Inference Engine Version",
"ReplicaNumber": "Replica Number",
"ImportAndStartService": "Import & Start Service",
"huggingFaceUrlPlaceholder": "Input Hugging Face URL"
}
},
"dialog": {
"warning": {
Expand Down
11 changes: 10 additions & 1 deletion resources/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,16 @@
"Add": "Añadir",
"CloningIsOnlyPossibleSameHost": "Actualmente, la clonación sólo es posible en el mismo host.",
"userQuotaScopeId": "Quota Scope ID",
"NewFolderName": "Nuevo nombre de carpeta"
"NewFolderName": "Nuevo nombre de carpeta",
"modelStore": {
"ImportFromHuggingFace": "Importar desde Hugging Face",
"Import": "Importar",
"StartService": "Comienza el servicio",
"InferenceEngineVersion": "Versión del motor de inferencia",
"ReplicaNumber": "Número de réplica",
"ImportAndStartService": "Servicio de importación e inicio",
"huggingFaceUrlPlaceholder": "Introduzca la URL Hugging Face"
}
},
"dialog": {
"warning": {
Expand Down
11 changes: 10 additions & 1 deletion resources/i18n/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,16 @@
"CloningIsOnlyPossibleSameHost": "Tällä hetkellä kloonaus on mahdollista vain samassa isännässä.",
"New": "Uusi",
"userQuotaScopeId": "Quota Scope ID",
"NewFolderName": "Uusi kansion nimi"
"NewFolderName": "Uusi kansion nimi",
"modelStore": {
"ImportFromHuggingFace": "Tuo hugging Face sta",
"Import": "Tuonti",
"StartService": "Aloita palvelu",
"InferenceEngineVersion": "Päättele moottorin versio",
"ReplicaNumber": "Replikan numero",
"ImportAndStartService": "Tuo ja käynnistä palvelu",
"huggingFaceUrlPlaceholder": "Syötä Hugging Face-URL-osoite"
}
},
"dialog": {
"warning": {
Expand Down
11 changes: 10 additions & 1 deletion resources/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,16 @@
"Add": "Ajouter",
"CloningIsOnlyPossibleSameHost": "Actuellement, le clonage n'est possible que sur le même hôte.",
"userQuotaScopeId": "Quota Scope ID",
"NewFolderName": "Nouveau nom de dossier"
"NewFolderName": "Nouveau nom de dossier",
"modelStore": {
"ImportFromHuggingFace": "Importer à partir de Hugging Face",
"Import": "Importer",
"StartService": "Démarrer le service",
"InferenceEngineVersion": "Version du moteur d'inférence",
"ReplicaNumber": "Numéro de réplique",
"ImportAndStartService": "Service d'importation et de démarrage",
"huggingFaceUrlPlaceholder": "Saisissez l'URL Hugging Face"
}
},
"dialog": {
"warning": {
Expand Down
11 changes: 10 additions & 1 deletion resources/i18n/id.json
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,16 @@
"Add": "Menambahkan",
"CloningIsOnlyPossibleSameHost": "Saat ini, kloning hanya dapat dilakukan pada host yang sama.",
"userQuotaScopeId": "Quota Scope ID",
"NewFolderName": "Nama folder baru"
"NewFolderName": "Nama folder baru",
"modelStore": {
"ImportFromHuggingFace": "Impor Dari Hugging Face",
"Import": "Impor",
"StartService": "Memulai layanan",
"InferenceEngineVersion": "Versi Mesin Inferensi",
"ReplicaNumber": "Nomor Replika",
"ImportAndStartService": "Impor dan Mulai Layanan",
"huggingFaceUrlPlaceholder": "Masukkan URL Hugging Face"
}
},
"dialog": {
"warning": {
Expand Down
11 changes: 10 additions & 1 deletion resources/i18n/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,16 @@
"Add": "Aggiungi",
"CloningIsOnlyPossibleSameHost": "Attualmente la clonazione è possibile solo sullo stesso host.",
"userQuotaScopeId": "Quota Scope ID",
"NewFolderName": "Nuovo nome della cartella"
"NewFolderName": "Nuovo nome della cartella",
"modelStore": {
"ImportFromHuggingFace": "Importa da Hugging Face",
"Import": "Importare",
"StartService": "Avvia servizio",
"InferenceEngineVersion": "Versione del motore di inferenza",
"ReplicaNumber": "Numero di replica",
"ImportAndStartService": "Importa e avvia il servizio",
"huggingFaceUrlPlaceholder": "Inserisci l'URL Hugging Face."
}
},
"dialog": {
"warning": {
Expand Down
11 changes: 10 additions & 1 deletion resources/i18n/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,16 @@
"Add": "追加",
"CloningIsOnlyPossibleSameHost": "現在、クローン作成は同じホスト上でのみ可能です。",
"userQuotaScopeId": "Quota Scope ID",
"NewFolderName": "新しいフォルダ名"
"NewFolderName": "新しいフォルダ名",
"modelStore": {
"ImportFromHuggingFace": "「ハグフェイス」からインポート",
"Import": "輸入",
"StartService": "サービスを開始する",
"InferenceEngineVersion": "推論エンジンのバージョン",
"ReplicaNumber": "レプリカ番号",
"ImportAndStartService": "サービスのインポートと開始",
"huggingFaceUrlPlaceholder": "Hugging Faceの URL を入力してください"
}
},
"dialog": {
"warning": {
Expand Down
Loading

0 comments on commit 7fd4eff

Please sign in to comment.