474 lines
10 KiB
TypeScript
474 lines
10 KiB
TypeScript
import { ListItem as UserListItem } from '@/pages/users/config/types';
|
|
import { downloadFile, listFiles, listModels } from '@huggingface/hub';
|
|
import { PipelineType } from '@huggingface/tasks';
|
|
import { request } from '@umijs/max';
|
|
import qs from 'query-string';
|
|
import {
|
|
AccessControlFormData,
|
|
BackendItem,
|
|
CatalogItem,
|
|
CatalogSpec,
|
|
DraftModelItem,
|
|
EvaluateResult,
|
|
EvaluateSpec,
|
|
FormData,
|
|
GPUListItem,
|
|
ListItem,
|
|
ModelInstanceFormData,
|
|
ModelInstanceListItem
|
|
} from '../config/types';
|
|
|
|
export const MODELS_API = '/models';
|
|
|
|
export const MODEL_INSTANCE_API = '/model-instances';
|
|
|
|
export const MODEL_EVALUATIONS = '/model-evaluations';
|
|
|
|
export const BACKEND_LIST_API = '/inference-backends/list';
|
|
|
|
export const MY_MODELS_API = '/my-models';
|
|
|
|
export const DRAFT_MODELS_API = '/draft-models';
|
|
|
|
export const CATALOG_LIST_API = '/model-sets';
|
|
|
|
const setProxyUrl = (url: string) => {
|
|
return `/proxy?url=${encodeURIComponent(url)}`;
|
|
};
|
|
|
|
// ===================== Models =====================
|
|
|
|
export async function queryModelsInstances(
|
|
params: Global.SearchParams,
|
|
options?: any
|
|
) {
|
|
return request<Global.PageResponse<ModelInstanceListItem>>(
|
|
MODEL_INSTANCE_API,
|
|
{
|
|
params,
|
|
method: 'GET',
|
|
cancelToken: options?.token
|
|
}
|
|
);
|
|
}
|
|
export async function queryModelsList(
|
|
params: Global.SearchParams,
|
|
options?: Record<string, any>
|
|
) {
|
|
return request<Global.PageResponse<ListItem>>(
|
|
`${MODELS_API}?${qs.stringify(params)}`,
|
|
{
|
|
method: 'GET',
|
|
...options
|
|
}
|
|
);
|
|
}
|
|
|
|
export async function queryGPUList<T extends Record<string, any>>(
|
|
params?: Global.SearchParams & T
|
|
) {
|
|
return request<Global.PageResponse<GPUListItem>>(`/gpu-devices`, {
|
|
method: 'GET',
|
|
params
|
|
});
|
|
}
|
|
|
|
export async function createModel(params: { data: FormData }) {
|
|
return request(`${MODELS_API}`, {
|
|
method: 'POST',
|
|
data: params.data
|
|
});
|
|
}
|
|
|
|
export async function deleteModel(id: number) {
|
|
return request(`${MODELS_API}/${id}`, {
|
|
method: 'DELETE'
|
|
});
|
|
}
|
|
|
|
export async function updateModel(params: { id: number; data: FormData }) {
|
|
return request(`${MODELS_API}/${params.id}`, {
|
|
method: 'PUT',
|
|
data: params.data
|
|
});
|
|
}
|
|
|
|
export async function queryModelDetail(id: number) {
|
|
return request(`${MODELS_API}/${id}`, {
|
|
method: 'GET'
|
|
});
|
|
}
|
|
|
|
// ===================== Model Instances start =====================
|
|
|
|
export async function queryModelInstancesList(
|
|
params: Global.Pagination & { query?: string; id: number },
|
|
options?: any
|
|
) {
|
|
return request<Global.PageResponse<ModelInstanceListItem>>(
|
|
`${MODELS_API}/${params.id}/instances`,
|
|
{
|
|
method: 'GET',
|
|
params,
|
|
cancelToken: options?.token
|
|
}
|
|
);
|
|
}
|
|
|
|
export async function createModelInstance(params: {
|
|
data: ModelInstanceFormData;
|
|
}) {
|
|
return request(`${MODEL_INSTANCE_API}`, {
|
|
method: 'POST',
|
|
data: params.data
|
|
});
|
|
}
|
|
|
|
export async function deleteModelInstance(id: number) {
|
|
return request(`${MODEL_INSTANCE_API}/${id}`, {
|
|
method: 'DELETE'
|
|
});
|
|
}
|
|
|
|
export async function updateModelInstance(params: {
|
|
id: number;
|
|
data: FormData;
|
|
}) {
|
|
return request(`${MODEL_INSTANCE_API}/${params.id}`, {
|
|
method: 'PUT',
|
|
data: params.data
|
|
});
|
|
}
|
|
|
|
export async function queryModelInstanceDetail(id: number) {
|
|
return request(`${MODEL_INSTANCE_API}/${id}`, {
|
|
method: 'GET'
|
|
});
|
|
}
|
|
|
|
export async function queryModelInstanceLogs(id: number) {
|
|
return request(`${MODEL_INSTANCE_API}/${id}/logs`, {
|
|
method: 'GET'
|
|
});
|
|
}
|
|
|
|
// ===================== Model Instances end =====================
|
|
|
|
// ===================== call huggingface quicksearch api =====================
|
|
|
|
const MODEL_SCOPE_LIST_MODEL_API = `https://www.modelscope.cn/api/v1/dolphin/models`;
|
|
|
|
const MODE_SCOPE_MODEL_FIELS_API = `https://modelscope.cn/api/v1/models/`;
|
|
|
|
export async function queryHuggingfaceModelDetail(
|
|
params: { repo: string },
|
|
options?: any
|
|
) {
|
|
const url = `https://huggingface.co/api/models/${params.repo}`;
|
|
return request(setProxyUrl(url), {
|
|
method: 'GET',
|
|
cancelToken: options?.token
|
|
});
|
|
}
|
|
|
|
export async function queryModelScopeModels(
|
|
params: {
|
|
PageSize?: number;
|
|
PageNumber?: number;
|
|
SortBy?: string;
|
|
Target?: string;
|
|
SingleCriterion?: any[];
|
|
Name: string;
|
|
tags?: string[];
|
|
tasks?: string[];
|
|
},
|
|
config?: any
|
|
) {
|
|
const tagsCriterion = params.tags?.map((tag: string) => {
|
|
return { category: 'tags', predicate: 'contains', values: [tag] };
|
|
});
|
|
const tasksCriterion = params.tasks?.map((task: string) => {
|
|
return { category: 'tasks', predicate: 'contains', values: [task] };
|
|
});
|
|
|
|
const Criterion =
|
|
tagsCriterion?.length || tasksCriterion?.length
|
|
? {
|
|
Criterion: [...(tagsCriterion || []), ...(tasksCriterion || [])]
|
|
}
|
|
: {};
|
|
|
|
const res = await fetch(setProxyUrl(`${MODEL_SCOPE_LIST_MODEL_API}`), {
|
|
method: 'PUT',
|
|
signal: config?.signal,
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
PageSize: 10,
|
|
PageNumber: 1,
|
|
...params,
|
|
...Criterion,
|
|
Name: `${params.Name}`
|
|
})
|
|
});
|
|
if (!res.ok) {
|
|
throw new Error('Network response was not ok');
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function queryModelScopeModelDetail(
|
|
params: { name: string },
|
|
options?: any
|
|
) {
|
|
return request(setProxyUrl(`${MODE_SCOPE_MODEL_FIELS_API}${params.name}`), {
|
|
method: 'GET',
|
|
cancelToken: options?.token
|
|
});
|
|
}
|
|
|
|
export async function queryModelScopeModelFiles(
|
|
params: { name: string; revision: string },
|
|
options?: any
|
|
) {
|
|
const url = `${MODE_SCOPE_MODEL_FIELS_API}${params.name}/repo/files?${qs.stringify(
|
|
{
|
|
Revision: params.revision,
|
|
Recursive: true,
|
|
Root: ''
|
|
}
|
|
)}`;
|
|
const res = await fetch(setProxyUrl(url), {
|
|
method: 'GET',
|
|
signal: options?.signal,
|
|
body: null
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error('Network response was not ok');
|
|
}
|
|
|
|
return res.json();
|
|
}
|
|
|
|
// list models from huggingface
|
|
export async function queryHuggingfaceModels(
|
|
params: {
|
|
limit?: number;
|
|
search: {
|
|
query: string;
|
|
tags?: string[];
|
|
sort?: string;
|
|
task?: PipelineType;
|
|
};
|
|
},
|
|
options?: any
|
|
) {
|
|
console.log('params', params);
|
|
const result = [];
|
|
for await (const model of listModels({
|
|
...params,
|
|
...options,
|
|
limit: params.limit || 500,
|
|
additionalFields: ['sha', 'tags'],
|
|
fetch(_url: string, config: any) {
|
|
const url = params.search.sort
|
|
? `${_url}&sort=${params.search.sort}`
|
|
: _url;
|
|
try {
|
|
return fetch(setProxyUrl(url), {
|
|
...config,
|
|
signal: options.signal
|
|
});
|
|
} catch (error) {
|
|
// ignore
|
|
return [];
|
|
}
|
|
}
|
|
})) {
|
|
result.push(model);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// list files from huggingface
|
|
export async function queryHuggingfaceModelFiles(
|
|
params: { repo: string },
|
|
options?: any
|
|
) {
|
|
const result = [];
|
|
for await (const fileInfo of listFiles({
|
|
...params,
|
|
recursive: true,
|
|
fetch(url: string, config: any) {
|
|
try {
|
|
return fetch(setProxyUrl(url), {
|
|
...config,
|
|
signal: options?.signal
|
|
});
|
|
} catch (error) {
|
|
// ignore
|
|
return [];
|
|
}
|
|
}
|
|
})) {
|
|
result.push(fileInfo);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export async function downloadModelFile(
|
|
params: { repo: string; revision: string; path: string },
|
|
options?: any
|
|
) {
|
|
const { repo, revision, path } = params;
|
|
const res = await (
|
|
await downloadFile({
|
|
repo,
|
|
revision: revision,
|
|
path: path,
|
|
fetch(url: string, config: any) {
|
|
return fetch(setProxyUrl(url), {
|
|
...config,
|
|
signal: options?.signal
|
|
});
|
|
}
|
|
})
|
|
)?.text();
|
|
return res;
|
|
}
|
|
export async function downloadModelScopeModelfile(
|
|
params: { name: string },
|
|
options?: any
|
|
) {
|
|
const url = `${MODE_SCOPE_MODEL_FIELS_API}${params.name}/resolve/master/config.json`;
|
|
const res = await fetch(setProxyUrl(url), {
|
|
method: 'GET',
|
|
signal: options?.signal
|
|
});
|
|
if (!res.ok) {
|
|
throw new Error('Network response was not ok');
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
// ===================== catalog =====================
|
|
|
|
export async function queryCatalogList(
|
|
params: Global.SearchParams,
|
|
options?: any
|
|
) {
|
|
return request<Global.PageResponse<CatalogItem>>(`${CATALOG_LIST_API}`, {
|
|
method: 'GET',
|
|
params,
|
|
cancelToken: options?.token
|
|
});
|
|
}
|
|
|
|
export async function queryCatalogItemSpec(
|
|
params: { id: number; cluster_id: number | null },
|
|
options?: any
|
|
) {
|
|
return request<Global.PageResponse<CatalogSpec>>(
|
|
`${CATALOG_LIST_API}/${params.id}/specs`,
|
|
{
|
|
method: 'GET',
|
|
...options,
|
|
params
|
|
}
|
|
);
|
|
}
|
|
|
|
export async function evaluationsModelSpec(
|
|
data: {
|
|
cluster_id: number;
|
|
model_specs: EvaluateSpec[];
|
|
},
|
|
options: { token: any }
|
|
) {
|
|
const result = await request<{ results: EvaluateResult[] }>(
|
|
`${MODEL_EVALUATIONS}`,
|
|
{
|
|
method: 'POST',
|
|
data,
|
|
cancelToken: options?.token
|
|
}
|
|
);
|
|
|
|
const resultList = result?.results || [];
|
|
|
|
return {
|
|
results: resultList.map((item) => {
|
|
return {
|
|
...item,
|
|
cluster_id: data.model_specs?.[0]?.cluster_id || undefined
|
|
};
|
|
})
|
|
};
|
|
}
|
|
|
|
export async function queryBackendList(params?: { cluster_id: number }) {
|
|
return request<{
|
|
items: BackendItem[];
|
|
}>(BACKEND_LIST_API, {
|
|
method: 'GET',
|
|
params
|
|
});
|
|
}
|
|
|
|
export async function queryModelAccessUserList(id: number) {
|
|
return request<{ items: UserListItem[] }>(`${MODELS_API}/${id}/access`, {
|
|
method: 'GET'
|
|
});
|
|
}
|
|
|
|
export async function updateModelAccessUser(params: {
|
|
id: number;
|
|
data: AccessControlFormData;
|
|
}) {
|
|
return request(`${MODELS_API}/${params.id}/access`, {
|
|
method: 'POST',
|
|
data: params.data
|
|
});
|
|
}
|
|
|
|
export async function queryMyModels(params: Global.SearchParams) {
|
|
return request<Global.PageResponse<ListItem>>(
|
|
`${MY_MODELS_API}?${qs.stringify(params)}`,
|
|
{
|
|
method: 'GET'
|
|
}
|
|
);
|
|
}
|
|
|
|
export async function queryMyModelDetail(id: number) {
|
|
return request(`${MY_MODELS_API}/${id}`, {
|
|
method: 'GET'
|
|
});
|
|
}
|
|
|
|
export async function queryDraftModelList(params?: Global.SearchParams) {
|
|
return request<{ items: DraftModelItem[] }>(DRAFT_MODELS_API, {
|
|
method: 'GET',
|
|
params
|
|
});
|
|
}
|
|
|
|
export async function queryModelContextLength(params: {
|
|
model: {
|
|
source: string;
|
|
model_scope_model_id?: string;
|
|
huggingface_repo_id?: string;
|
|
local_path?: string;
|
|
};
|
|
}) {
|
|
return request<{ native: number; scaled: number }>(
|
|
`${MODELS_API}/context-length`,
|
|
{
|
|
method: 'POST',
|
|
data: params
|
|
}
|
|
);
|
|
}
|