update
This commit is contained in:
parent
f6be32825f
commit
ac3e34e1d8
3
.gitignore
vendored
3
.gitignore
vendored
@ -3,4 +3,5 @@ node_modules
|
|||||||
frontend/dist
|
frontend/dist
|
||||||
.idea
|
.idea
|
||||||
.vs
|
.vs
|
||||||
package.json.md5
|
package.json.md5
|
||||||
|
cache.json
|
@ -5,13 +5,13 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *App) SaveConfig(config interface{}) string {
|
func (a *App) SaveJson(fileName string, jsonData interface{}) string {
|
||||||
jsonData, err := json.MarshalIndent(config, "", " ")
|
text, err := json.MarshalIndent(jsonData, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.WriteFile("config.json", jsonData, 0644); err != nil {
|
if err := os.WriteFile(fileName, text, 0644); err != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
100525
backend-python/20B_tokenizer.json
Normal file
100525
backend-python/20B_tokenizer.json
Normal file
File diff suppressed because it is too large
Load Diff
135
backend-python/main.py
Normal file
135
backend-python/main.py
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import json
|
||||||
|
import pathlib
|
||||||
|
import sys
|
||||||
|
from typing import List
|
||||||
|
import os
|
||||||
|
import sysconfig
|
||||||
|
|
||||||
|
from fastapi import FastAPI, Request, status, HTTPException
|
||||||
|
from langchain.llms import RWKV
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from sse_starlette.sse import EventSourceResponse
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
from rwkv_helper import rwkv_generate
|
||||||
|
|
||||||
|
|
||||||
|
def set_torch():
|
||||||
|
torch_path = os.path.join(sysconfig.get_paths()["purelib"], "torch\\lib")
|
||||||
|
paths = os.environ.get("PATH", "")
|
||||||
|
if os.path.exists(torch_path):
|
||||||
|
print(f"torch found: {torch_path}")
|
||||||
|
if torch_path in paths:
|
||||||
|
print("torch already set")
|
||||||
|
else:
|
||||||
|
print("run:")
|
||||||
|
os.environ['PATH'] = paths + os.pathsep + torch_path + os.pathsep
|
||||||
|
print(f'set Path={paths + os.pathsep + torch_path + os.pathsep}')
|
||||||
|
else:
|
||||||
|
print("torch not found")
|
||||||
|
|
||||||
|
|
||||||
|
def torch_gc():
|
||||||
|
import torch
|
||||||
|
|
||||||
|
if torch.cuda.is_available():
|
||||||
|
with torch.cuda.device(0):
|
||||||
|
torch.cuda.empty_cache()
|
||||||
|
torch.cuda.ipc_collect()
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_event('startup')
|
||||||
|
def init():
|
||||||
|
global model
|
||||||
|
|
||||||
|
set_torch()
|
||||||
|
|
||||||
|
model = RWKV(
|
||||||
|
model=sys.argv[2],
|
||||||
|
strategy=sys.argv[1],
|
||||||
|
tokens_path=f"{pathlib.Path(__file__).parent.resolve()}/20B_tokenizer.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
if os.environ.get("ngrok_token") is not None:
|
||||||
|
ngrok_connect()
|
||||||
|
|
||||||
|
|
||||||
|
def ngrok_connect():
|
||||||
|
from pyngrok import ngrok, conf
|
||||||
|
conf.set_default(conf.PyngrokConfig(ngrok_path="./ngrok"))
|
||||||
|
ngrok.set_auth_token(os.environ["ngrok_token"])
|
||||||
|
http_tunnel = ngrok.connect(8000)
|
||||||
|
print(http_tunnel.public_url)
|
||||||
|
|
||||||
|
|
||||||
|
class Message(BaseModel):
|
||||||
|
role: str
|
||||||
|
content: str
|
||||||
|
|
||||||
|
|
||||||
|
class Body(BaseModel):
|
||||||
|
messages: List[Message]
|
||||||
|
model: str
|
||||||
|
stream: bool
|
||||||
|
max_tokens: int
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
def read_root():
|
||||||
|
return {"Hello": "World!"}
|
||||||
|
|
||||||
|
@app.post("update-config")
|
||||||
|
def updateConfig(body: Body):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/v1/chat/completions")
|
||||||
|
@app.post("/chat/completions")
|
||||||
|
async def completions(body: Body, request: Request):
|
||||||
|
global model
|
||||||
|
|
||||||
|
question = body.messages[-1]
|
||||||
|
if question.role == 'user':
|
||||||
|
question = question.content
|
||||||
|
else:
|
||||||
|
raise HTTPException(status.HTTP_400_BAD_REQUEST, "No Question Found")
|
||||||
|
|
||||||
|
completion_text = ""
|
||||||
|
for message in body.messages:
|
||||||
|
if message.role == 'user':
|
||||||
|
completion_text += "Bob: " + message.content + "\n\n"
|
||||||
|
elif message.role == 'assistant':
|
||||||
|
completion_text += "Alice: " + message.content + "\n\n"
|
||||||
|
completion_text += "Alice:"
|
||||||
|
|
||||||
|
async def eval_rwkv():
|
||||||
|
if body.stream:
|
||||||
|
for response, delta in rwkv_generate(model, completion_text):
|
||||||
|
if await request.is_disconnected():
|
||||||
|
break
|
||||||
|
yield json.dumps({"response": response, "choices": [{"delta": {"content": delta}}], "model": "rwkv"})
|
||||||
|
yield "[DONE]"
|
||||||
|
else:
|
||||||
|
response = None
|
||||||
|
for response, delta in rwkv_generate(model, completion_text):
|
||||||
|
pass
|
||||||
|
yield json.dumps({"response": response, "model": "rwkv"})
|
||||||
|
# torch_gc()
|
||||||
|
|
||||||
|
return EventSourceResponse(eval_rwkv())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
uvicorn.run("main:app", reload=False, app_dir="backend-python")
|
40
backend-python/rwkv_helper.py
Normal file
40
backend-python/rwkv_helper.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
from typing import Dict
|
||||||
|
from langchain.llms import RWKV
|
||||||
|
|
||||||
|
|
||||||
|
def rwkv_generate(model: RWKV, prompt: str):
|
||||||
|
model.model_state = None
|
||||||
|
model.model_tokens = []
|
||||||
|
logits = model.run_rnn(model.tokenizer.encode(prompt).ids)
|
||||||
|
begin = len(model.model_tokens)
|
||||||
|
out_last = begin
|
||||||
|
|
||||||
|
occurrence: Dict = {}
|
||||||
|
|
||||||
|
response = ""
|
||||||
|
for i in range(model.max_tokens_per_generation):
|
||||||
|
for n in occurrence:
|
||||||
|
logits[n] -= (
|
||||||
|
model.penalty_alpha_presence
|
||||||
|
+ occurrence[n] * model.penalty_alpha_frequency
|
||||||
|
)
|
||||||
|
token = model.pipeline.sample_logits(
|
||||||
|
logits, temperature=model.temperature, top_p=model.top_p
|
||||||
|
)
|
||||||
|
|
||||||
|
END_OF_TEXT = 0
|
||||||
|
if token == END_OF_TEXT:
|
||||||
|
break
|
||||||
|
if token not in occurrence:
|
||||||
|
occurrence[token] = 1
|
||||||
|
else:
|
||||||
|
occurrence[token] += 1
|
||||||
|
|
||||||
|
logits = model.run_rnn([token])
|
||||||
|
delta: str = model.tokenizer.decode(model.model_tokens[out_last:])
|
||||||
|
if "\ufffd" not in delta: # avoid utf-8 display issues
|
||||||
|
response += delta
|
||||||
|
yield response, delta
|
||||||
|
out_last = begin + i + 1
|
||||||
|
if i >= model.max_tokens_per_generation - 100:
|
||||||
|
break
|
19
frontend/package-lock.json
generated
19
frontend/package-lock.json
generated
@ -13,7 +13,8 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-router": "^6.11.0",
|
"react-router": "^6.11.0",
|
||||||
"react-router-dom": "^6.11.0"
|
"react-router-dom": "^6.11.0",
|
||||||
|
"usehooks-ts": "^2.9.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.0.17",
|
"@types/react": "^18.0.17",
|
||||||
@ -3315,6 +3316,22 @@
|
|||||||
"react-dom": ">=16.8.0 <19.0.0"
|
"react-dom": ">=16.8.0 <19.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/usehooks-ts": {
|
||||||
|
"version": "2.9.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/usehooks-ts/-/usehooks-ts-2.9.1.tgz",
|
||||||
|
"integrity": "sha512-2FAuSIGHlY+apM9FVlj8/oNhd+1y+Uwv5QNkMQz1oSfdHk4PXo1qoCw9I5M7j0vpH8CSWFJwXbVPeYDjLCx9PA==",
|
||||||
|
"workspaces": [
|
||||||
|
"packages/eslint-config-custom"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.15.0",
|
||||||
|
"npm": ">=8"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-router": "^6.11.0",
|
"react-router": "^6.11.0",
|
||||||
"react-router-dom": "^6.11.0"
|
"react-router-dom": "^6.11.0",
|
||||||
|
"usehooks-ts": "^2.9.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.0.17",
|
"@types/react": "^18.0.17",
|
||||||
|
@ -27,10 +27,12 @@ import {FluentProvider, Tab, TabList, webDarkTheme} from '@fluentui/react-compon
|
|||||||
import {FC, useEffect, useState} from 'react';
|
import {FC, useEffect, useState} from 'react';
|
||||||
import {Route, Routes, useLocation, useNavigate} from 'react-router';
|
import {Route, Routes, useLocation, useNavigate} from 'react-router';
|
||||||
import {pages} from './Pages';
|
import {pages} from './Pages';
|
||||||
|
import {useMediaQuery} from 'usehooks-ts';
|
||||||
|
|
||||||
const App: FC = () => {
|
const App: FC = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
const mq = useMediaQuery('(min-width: 640px)');
|
||||||
|
|
||||||
const [path, setPath] = useState<string>(pages[0].path);
|
const [path, setPath] = useState<string>(pages[0].path);
|
||||||
|
|
||||||
@ -42,7 +44,7 @@ const App: FC = () => {
|
|||||||
return (
|
return (
|
||||||
<FluentProvider theme={webDarkTheme} className="h-screen">
|
<FluentProvider theme={webDarkTheme} className="h-screen">
|
||||||
<div className="flex h-full">
|
<div className="flex h-full">
|
||||||
<div className="flex flex-col w-40 p-2 justify-between">
|
<div className="flex flex-col w-16 sm:w-48 p-2 justify-between">
|
||||||
<TabList
|
<TabList
|
||||||
size="large"
|
size="large"
|
||||||
appearance="subtle"
|
appearance="subtle"
|
||||||
@ -50,9 +52,9 @@ const App: FC = () => {
|
|||||||
onTabSelect={(_, {value}) => selectTab(value)}
|
onTabSelect={(_, {value}) => selectTab(value)}
|
||||||
vertical
|
vertical
|
||||||
>
|
>
|
||||||
{pages.filter(page=>page.top).map(({label, path, icon}, index) => (
|
{pages.filter(page => page.top).map(({label, path, icon}, index) => (
|
||||||
<Tab icon={icon} key={`${path}-${index}`} value={path}>
|
<Tab icon={icon} key={`${path}-${index}`} value={path}>
|
||||||
{label}
|
{mq && label}
|
||||||
</Tab>
|
</Tab>
|
||||||
))}
|
))}
|
||||||
</TabList>
|
</TabList>
|
||||||
@ -63,9 +65,9 @@ const App: FC = () => {
|
|||||||
onTabSelect={(_, {value}) => selectTab(value)}
|
onTabSelect={(_, {value}) => selectTab(value)}
|
||||||
vertical
|
vertical
|
||||||
>
|
>
|
||||||
{pages.filter(page=>!page.top).map(({label, path, icon}, index) => (
|
{pages.filter(page => !page.top).map(({label, path, icon}, index) => (
|
||||||
<Tab icon={icon} key={`${path}-${index}`} value={path}>
|
<Tab icon={icon} key={`${path}-${index}`} value={path}>
|
||||||
{label}
|
{mq && label}
|
||||||
</Tab>
|
</Tab>
|
||||||
))}
|
))}
|
||||||
</TabList>
|
</TabList>
|
||||||
|
@ -1,269 +1,86 @@
|
|||||||
import {
|
import {Button, Divider, Dropdown, Input, Option, Slider, Switch, Text} from '@fluentui/react-components';
|
||||||
Avatar,
|
import {AddCircle20Regular, DataUsageSettings20Regular, Delete20Regular, Save20Regular} from '@fluentui/react-icons';
|
||||||
Button,
|
|
||||||
createTableColumn,
|
|
||||||
Dropdown,
|
|
||||||
Input,
|
|
||||||
PresenceBadgeStatus,
|
|
||||||
Select,
|
|
||||||
Slider,
|
|
||||||
Switch,
|
|
||||||
TableCellLayout,
|
|
||||||
TableColumnDefinition,
|
|
||||||
Text,
|
|
||||||
Tooltip
|
|
||||||
} from '@fluentui/react-components';
|
|
||||||
import {
|
|
||||||
AddCircle20Regular,
|
|
||||||
Delete20Regular,
|
|
||||||
DocumentPdfRegular,
|
|
||||||
DocumentRegular,
|
|
||||||
EditRegular,
|
|
||||||
FolderRegular,
|
|
||||||
OpenRegular,
|
|
||||||
PeopleRegular,
|
|
||||||
Save20Regular,
|
|
||||||
VideoRegular
|
|
||||||
} from '@fluentui/react-icons';
|
|
||||||
import React, {FC} from 'react';
|
import React, {FC} from 'react';
|
||||||
import {Section} from './components/Section';
|
import {Section} from './components/Section';
|
||||||
import {Labeled} from './components/Labeled';
|
import {Labeled} from './components/Labeled';
|
||||||
import {ToolTipButton} from './components/ToolTipButton';
|
import {ToolTipButton} from './components/ToolTipButton';
|
||||||
|
|
||||||
type FileCell = {
|
|
||||||
label: string;
|
|
||||||
icon: JSX.Element;
|
|
||||||
};
|
|
||||||
|
|
||||||
type LastUpdatedCell = {
|
|
||||||
label: string;
|
|
||||||
timestamp: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type LastUpdateCell = {
|
|
||||||
label: string;
|
|
||||||
icon: JSX.Element;
|
|
||||||
};
|
|
||||||
|
|
||||||
type AuthorCell = {
|
|
||||||
label: string;
|
|
||||||
status: PresenceBadgeStatus;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Item = {
|
|
||||||
file: FileCell;
|
|
||||||
author: AuthorCell;
|
|
||||||
lastUpdated: LastUpdatedCell;
|
|
||||||
lastUpdate: LastUpdateCell;
|
|
||||||
};
|
|
||||||
|
|
||||||
const items: Item[] = [
|
|
||||||
{
|
|
||||||
file: {label: 'Meeting notes', icon: <DocumentRegular/>},
|
|
||||||
author: {label: 'Max Mustermann', status: 'available'},
|
|
||||||
lastUpdated: {label: '7h ago', timestamp: 1},
|
|
||||||
lastUpdate: {
|
|
||||||
label: 'You edited this',
|
|
||||||
icon: <EditRegular/>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
file: {label: 'Thursday presentation', icon: <FolderRegular/>},
|
|
||||||
author: {label: 'Erika Mustermann', status: 'busy'},
|
|
||||||
lastUpdated: {label: 'Yesterday at 1:45 PM', timestamp: 2},
|
|
||||||
lastUpdate: {
|
|
||||||
label: 'You recently opened this',
|
|
||||||
icon: <OpenRegular/>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
file: {label: 'Training recording', icon: <VideoRegular/>},
|
|
||||||
author: {label: 'John Doe', status: 'away'},
|
|
||||||
lastUpdated: {label: 'Yesterday at 1:45 PM', timestamp: 2},
|
|
||||||
lastUpdate: {
|
|
||||||
label: 'You recently opened this',
|
|
||||||
icon: <OpenRegular/>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
file: {label: 'Purchase order', icon: <DocumentPdfRegular/>},
|
|
||||||
author: {label: 'Jane Doe', status: 'offline'},
|
|
||||||
lastUpdated: {label: 'Tue at 9:30 AM', timestamp: 3},
|
|
||||||
lastUpdate: {
|
|
||||||
label: 'You shared this in a Teams chat',
|
|
||||||
icon: <PeopleRegular/>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const columns: TableColumnDefinition<Item>[] = [
|
|
||||||
createTableColumn<Item>({
|
|
||||||
columnId: 'file',
|
|
||||||
compare: (a, b) => {
|
|
||||||
return a.file.label.localeCompare(b.file.label);
|
|
||||||
},
|
|
||||||
renderHeaderCell: () => {
|
|
||||||
return 'File';
|
|
||||||
},
|
|
||||||
renderCell: (item) => {
|
|
||||||
return (
|
|
||||||
<TableCellLayout media={item.file.icon}>
|
|
||||||
{item.file.label}
|
|
||||||
</TableCellLayout>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
createTableColumn<Item>({
|
|
||||||
columnId: 'author',
|
|
||||||
compare: (a, b) => {
|
|
||||||
return a.author.label.localeCompare(b.author.label);
|
|
||||||
},
|
|
||||||
renderHeaderCell: () => {
|
|
||||||
return 'Author';
|
|
||||||
},
|
|
||||||
renderCell: (item) => {
|
|
||||||
return (
|
|
||||||
<TableCellLayout
|
|
||||||
media={
|
|
||||||
<Avatar
|
|
||||||
aria-label={item.author.label}
|
|
||||||
name={item.author.label}
|
|
||||||
badge={{status: item.author.status}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{item.author.label}
|
|
||||||
</TableCellLayout>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
createTableColumn<Item>({
|
|
||||||
columnId: 'lastUpdated',
|
|
||||||
compare: (a, b) => {
|
|
||||||
return a.lastUpdated.timestamp - b.lastUpdated.timestamp;
|
|
||||||
},
|
|
||||||
renderHeaderCell: () => {
|
|
||||||
return 'Last updated';
|
|
||||||
},
|
|
||||||
|
|
||||||
renderCell: (item) => {
|
|
||||||
return item.lastUpdated.label;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
createTableColumn<Item>({
|
|
||||||
columnId: 'lastUpdate',
|
|
||||||
compare: (a, b) => {
|
|
||||||
return a.lastUpdate.label.localeCompare(b.lastUpdate.label);
|
|
||||||
},
|
|
||||||
renderHeaderCell: () => {
|
|
||||||
return 'Last update';
|
|
||||||
},
|
|
||||||
renderCell: (item) => {
|
|
||||||
return (
|
|
||||||
<TableCellLayout media={item.lastUpdate.icon}>
|
|
||||||
{item.lastUpdate.label}
|
|
||||||
</TableCellLayout>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
// <DataGrid
|
|
||||||
// items={items}
|
|
||||||
// columns={columns}
|
|
||||||
// >
|
|
||||||
// <DataGridBody<Item>>
|
|
||||||
// {({ item, rowId }) => (
|
|
||||||
// <DataGridRow<Item> key={rowId}>
|
|
||||||
// {({ renderCell }) => (
|
|
||||||
// <DataGridCell>{renderCell(item)}</DataGridCell>
|
|
||||||
// )}
|
|
||||||
// </DataGridRow>
|
|
||||||
// )}
|
|
||||||
// </DataGridBody>
|
|
||||||
// </DataGrid>
|
|
||||||
|
|
||||||
export const Configs: FC = () => {
|
export const Configs: FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col box-border gap-5 p-2">
|
<div className="flex flex-col gap-2 p-2 h-full">
|
||||||
<Text size={600}>Configs</Text>
|
<Text size={600}>Configs</Text>
|
||||||
<Section
|
<Divider/>
|
||||||
title="Config List"
|
<div className="flex gap-2 items-center w-full">
|
||||||
content={
|
<Dropdown style={{minWidth: 0}} className="grow"/>
|
||||||
<div className="flex gap-5 items-center w-full">
|
<ToolTipButton desc="New Config" icon={<AddCircle20Regular/>}/>
|
||||||
<Dropdown className="w-full"/>
|
<ToolTipButton desc="Delete Config" icon={<Delete20Regular/>}/>
|
||||||
<ToolTipButton desc="New Config" icon={<AddCircle20Regular/>}/>
|
<ToolTipButton desc="Save Config" icon={<Save20Regular/>}/>
|
||||||
<ToolTipButton desc="Delete Config" icon={<Delete20Regular/>}/>
|
</div>
|
||||||
<ToolTipButton desc="Save Config" icon={<Save20Regular/>}/>
|
<div className="flex flex-col h-full gap-2 overflow-y-hidden">
|
||||||
</div>
|
<Section
|
||||||
}
|
title="Default API Parameters"
|
||||||
/>
|
desc="Hover your mouse over the text to view a detailed description. Settings marked with * will take effect immediately after being saved."
|
||||||
<Section
|
content={
|
||||||
title="Default API Parameters"
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
|
||||||
desc="Hover your mouse over the text to view a detailed description. Settings marked with * will take effect immediately after being saved."
|
|
||||||
content={
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<div className="grid grid-cols-2">
|
|
||||||
<Labeled label="API Port" desc="127.0.0.1:8000" content={
|
<Labeled label="API Port" desc="127.0.0.1:8000" content={
|
||||||
<Input type="number" min={1} max={65535} step={1}/>
|
<Input type="number" min={1} max={65535} step={1}/>
|
||||||
}/>
|
}/>
|
||||||
<Labeled label="Max Response Token *" content={
|
<Labeled label="Max Response Token *" content={
|
||||||
<div className="flex items-center">
|
<div className="flex items-center grow">
|
||||||
<Slider className="w-48" step={400} min={100} max={8100}/>
|
<Slider style={{minWidth: 0}} className="grow" step={400} min={100} max={8100}/>
|
||||||
<Text>1000</Text>
|
<Text>1000</Text>
|
||||||
</div>
|
</div>
|
||||||
}/>
|
}/>
|
||||||
</div>
|
|
||||||
<div className="grid grid-cols-2">
|
|
||||||
<Labeled label="Temperature *" content={
|
<Labeled label="Temperature *" content={
|
||||||
<Slider/>
|
<Slider style={{minWidth: 0}} className="grow"/>
|
||||||
}/>
|
}/>
|
||||||
<Labeled label="Top_P *" content={
|
<Labeled label="Top_P *" content={
|
||||||
<Slider/>
|
<Slider style={{minWidth: 0}} className="grow"/>
|
||||||
}/>
|
}/>
|
||||||
</div>
|
|
||||||
<div className="grid grid-cols-2">
|
|
||||||
<Labeled label="Presence Penalty *" content={
|
<Labeled label="Presence Penalty *" content={
|
||||||
<Slider/>
|
<Slider style={{minWidth: 0}} className="grow"/>
|
||||||
}/>
|
}/>
|
||||||
<Labeled label="Count Penalty *" content={
|
<Labeled label="Count Penalty *" content={
|
||||||
<Slider/>
|
<Slider style={{minWidth: 0}} className="grow"/>
|
||||||
}/>
|
}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
}
|
/>
|
||||||
/>
|
<Section
|
||||||
<Section
|
title="Model Parameters"
|
||||||
title="Model Parameters"
|
content={
|
||||||
content={
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
|
||||||
<div className="flex flex-col gap-1">
|
<Labeled label="Model" content={
|
||||||
<div className="grid grid-cols-2">
|
<div className="flex gap-2 grow">
|
||||||
|
<Dropdown style={{minWidth: 0}} className="grow"/>
|
||||||
|
<ToolTipButton desc="Manage Models" icon={<DataUsageSettings20Regular/>}/>
|
||||||
|
</div>
|
||||||
|
}/>
|
||||||
|
<div/>
|
||||||
<Labeled label="Device" content={
|
<Labeled label="Device" content={
|
||||||
<Select className="w-28">
|
<Dropdown style={{minWidth: 0}} className="grow">
|
||||||
<option>CPU</option>
|
<Option>CPU</Option>
|
||||||
<option>CUDA: 0</option>
|
<Option>CUDA: 0</Option>
|
||||||
</Select>
|
</Dropdown>
|
||||||
}/>
|
}/>
|
||||||
<Labeled label="Precision" content={
|
<Labeled label="Precision" content={
|
||||||
<Select className="w-28">
|
<Dropdown style={{minWidth: 0}} className="grow">
|
||||||
<option>fp16</option>
|
<Option>fp16</Option>
|
||||||
<option>int8</option>
|
<Option>int8</Option>
|
||||||
<option>fp32</option>
|
<Option>fp32</Option>
|
||||||
</Select>
|
</Dropdown>
|
||||||
}/>
|
}/>
|
||||||
</div>
|
|
||||||
<div className="grid grid-cols-2">
|
|
||||||
<Labeled label="Streamed Layers" content={
|
<Labeled label="Streamed Layers" content={
|
||||||
<Slider/>
|
<Slider style={{minWidth: 0}} className="grow"/>
|
||||||
}/>
|
}/>
|
||||||
<Labeled label="Enable High Precision For Last Layer" content={
|
<Labeled label="Enable High Precision For Last Layer" content={
|
||||||
<Switch/>
|
<Switch/>
|
||||||
}/>
|
}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
}
|
/>
|
||||||
/>
|
</div>
|
||||||
<div className="fixed bottom-2 right-2">
|
<div className="flex flex-row-reverse sm:fixed bottom-2 right-2">
|
||||||
<Button appearance="primary" size="large">Run</Button>
|
<Button appearance="primary" size="large">Run</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
Storage20Regular
|
Storage20Regular
|
||||||
} from '@fluentui/react-icons';
|
} from '@fluentui/react-icons';
|
||||||
import {useNavigate} from 'react-router';
|
import {useNavigate} from 'react-router';
|
||||||
import {SaveConfig} from '../../wailsjs/go/backend_golang/App';
|
import {SaveJson} from '../../wailsjs/go/backend_golang/App';
|
||||||
|
|
||||||
type NavCard = {
|
type NavCard = {
|
||||||
label: string;
|
label: string;
|
||||||
@ -55,10 +55,10 @@ export const Home: FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col justify-between h-full">
|
<div className="flex flex-col justify-between h-full">
|
||||||
<img className="rounded-xl select-none" src={Banner}/>
|
<img className="rounded-xl select-none hidden sm:block" src={Banner}/>
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<Text size={600} weight="medium">Introduction</Text>
|
<Text size={600} weight="medium">Introduction</Text>
|
||||||
<Text size={300}>
|
<div className="h-40 overflow-y-auto">
|
||||||
RWKV is an RNN with Transformer-level LLM performance, which can also be directly trained like a GPT
|
RWKV is an RNN with Transformer-level LLM performance, which can also be directly trained like a GPT
|
||||||
transformer (parallelizable). And it's 100% attention-free. You only need the hidden state at position t to
|
transformer (parallelizable). And it's 100% attention-free. You only need the hidden state at position t to
|
||||||
compute the state at position t+1. You can use the "GPT" mode to quickly compute the hidden state for the
|
compute the state at position t+1. You can use the "GPT" mode to quickly compute the hidden state for the
|
||||||
@ -66,43 +66,47 @@ export const Home: FC = () => {
|
|||||||
<br/>
|
<br/>
|
||||||
So it's combining the best of RNN and transformer - great performance, fast inference, saves VRAM, fast
|
So it's combining the best of RNN and transformer - great performance, fast inference, saves VRAM, fast
|
||||||
training, "infinite" ctx_len, and free sentence embedding (using the final hidden state).
|
training, "infinite" ctx_len, and free sentence embedding (using the final hidden state).
|
||||||
</Text>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
<div className="grid grid-cols-2 sm:grid-cols-4 gap-5">
|
||||||
{navCards.map(({label, path, icon, desc}, index) => (
|
{navCards.map(({label, path, icon, desc}, index) => (
|
||||||
<CompoundButton className="w-1/5" icon={icon} secondaryContent={desc} key={`${path}-${index}`} value={path}
|
<CompoundButton icon={icon} secondaryContent={desc} key={`${path}-${index}`} value={path}
|
||||||
size="large" onClick={() => onClickNavCard(path)}>
|
size="large" onClick={() => onClickNavCard(path)}>
|
||||||
{label}
|
{label}
|
||||||
</CompoundButton>
|
</CompoundButton>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex flex-row-reverse sm:fixed bottom-2 right-2">
|
||||||
|
<div className="flex gap-3">
|
||||||
|
<Dropdown style={{minWidth: 0}}
|
||||||
|
placeholder="Config"
|
||||||
|
value={selectedConfig}
|
||||||
|
onOptionSelect={(_, data) => {
|
||||||
|
if (data.optionValue)
|
||||||
|
setSelectedConfig(data.optionValue);
|
||||||
|
}}>
|
||||||
|
<Option id="item-1" key="item-1">
|
||||||
|
RWKV-3B-4G MEM
|
||||||
|
</Option>
|
||||||
|
<Option id="item-2" key="item-2">
|
||||||
|
Item 2
|
||||||
|
</Option>
|
||||||
|
<Option id="item-3" key="item-3">
|
||||||
|
Item 3
|
||||||
|
</Option>
|
||||||
|
<Option id="item-4" key="item-4">
|
||||||
|
Item 4
|
||||||
|
</Option>
|
||||||
|
</Dropdown>
|
||||||
|
<Button appearance="primary" size="large"
|
||||||
|
onClick={() => SaveJson('config.json', {a: 1234, b: 'test'})}>Run</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="flex gap-4 items-end">
|
<div className="flex gap-4 items-end">
|
||||||
Version: 1.0.0
|
Version: 1.0.0
|
||||||
<Link>Help</Link>
|
<Link>Help</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-3">
|
|
||||||
<Dropdown placeholder="Config"
|
|
||||||
value={selectedConfig}
|
|
||||||
onOptionSelect={(_, data) => {
|
|
||||||
if (data.optionValue)
|
|
||||||
setSelectedConfig(data.optionValue);
|
|
||||||
}}>
|
|
||||||
<Option id="item-1" key="item-1">
|
|
||||||
RWKV-3B-4G MEM
|
|
||||||
</Option>
|
|
||||||
<Option id="item-2" key="item-2">
|
|
||||||
Item 2
|
|
||||||
</Option>
|
|
||||||
<Option id="item-3" key="item-3">
|
|
||||||
Item 3
|
|
||||||
</Option>
|
|
||||||
<Option id="item-4" key="item-4">
|
|
||||||
Item 4
|
|
||||||
</Option>
|
|
||||||
</Dropdown>
|
|
||||||
<Button appearance="primary" size="large" onClick={() => SaveConfig({a: 1234, b: 'test'})}>Run</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,10 +1,167 @@
|
|||||||
import React, {FC} from 'react';
|
import React, {FC, useEffect} from 'react';
|
||||||
import {Text} from '@fluentui/react-components';
|
import {
|
||||||
|
createTableColumn,
|
||||||
|
DataGrid,
|
||||||
|
DataGridBody,
|
||||||
|
DataGridCell,
|
||||||
|
DataGridHeader,
|
||||||
|
DataGridHeaderCell,
|
||||||
|
DataGridRow,
|
||||||
|
TableCellLayout,
|
||||||
|
TableColumnDefinition,
|
||||||
|
Text,
|
||||||
|
Textarea
|
||||||
|
} from '@fluentui/react-components';
|
||||||
|
import {EditRegular} from '@fluentui/react-icons/lib/fonts';
|
||||||
|
import {ToolTipButton} from './components/ToolTipButton';
|
||||||
|
import {ArrowClockwise20Regular} from '@fluentui/react-icons';
|
||||||
|
|
||||||
|
type Operation = {
|
||||||
|
icon: JSX.Element;
|
||||||
|
desc: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Item = {
|
||||||
|
filename: string;
|
||||||
|
desc: string;
|
||||||
|
size: number;
|
||||||
|
lastUpdated: number;
|
||||||
|
actions: Operation[];
|
||||||
|
isLocal: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const items: Item[] = [
|
||||||
|
{
|
||||||
|
filename: 'RWKV-4-Raven-14B-v11x-Eng99%-Other1%-20230501-ctx8192.pth',
|
||||||
|
desc: 'Mainly English language corpus',
|
||||||
|
size: 28297309490,
|
||||||
|
lastUpdated: 1,
|
||||||
|
actions: [{icon: <EditRegular/>, desc: 'Edit'}],
|
||||||
|
isLocal: false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const columns: TableColumnDefinition<Item>[] = [
|
||||||
|
createTableColumn<Item>({
|
||||||
|
columnId: 'file',
|
||||||
|
compare: (a, b) => {
|
||||||
|
return a.filename.localeCompare(b.filename);
|
||||||
|
},
|
||||||
|
renderHeaderCell: () => {
|
||||||
|
return 'File';
|
||||||
|
},
|
||||||
|
renderCell: (item) => {
|
||||||
|
return (
|
||||||
|
<TableCellLayout className="break-all">
|
||||||
|
{item.filename}
|
||||||
|
</TableCellLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
createTableColumn<Item>({
|
||||||
|
columnId: 'desc',
|
||||||
|
compare: (a, b) => {
|
||||||
|
return a.desc.localeCompare(b.desc);
|
||||||
|
},
|
||||||
|
renderHeaderCell: () => {
|
||||||
|
return 'Desc';
|
||||||
|
},
|
||||||
|
renderCell: (item) => {
|
||||||
|
return (
|
||||||
|
<TableCellLayout>
|
||||||
|
{item.desc}
|
||||||
|
</TableCellLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
createTableColumn<Item>({
|
||||||
|
columnId: 'size',
|
||||||
|
compare: (a, b) => {
|
||||||
|
return a.size - b.size;
|
||||||
|
},
|
||||||
|
renderHeaderCell: () => {
|
||||||
|
return 'Size';
|
||||||
|
},
|
||||||
|
renderCell: (item) => {
|
||||||
|
return (
|
||||||
|
<TableCellLayout>
|
||||||
|
{(item.size / (1024 * 1024 * 1024)).toFixed(2) + 'GB'}
|
||||||
|
</TableCellLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
createTableColumn<Item>({
|
||||||
|
columnId: 'lastUpdated',
|
||||||
|
compare: (a, b) => {
|
||||||
|
return a.lastUpdated - b.lastUpdated;
|
||||||
|
},
|
||||||
|
renderHeaderCell: () => {
|
||||||
|
return 'Last updated';
|
||||||
|
},
|
||||||
|
|
||||||
|
renderCell: (item) => {
|
||||||
|
return new Date(item.lastUpdated).toLocaleString();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
createTableColumn<Item>({
|
||||||
|
columnId: 'actions',
|
||||||
|
compare: (a, b) => {
|
||||||
|
return a.isLocal === b.isLocal ? 0 : a.isLocal ? -1 : 1;
|
||||||
|
},
|
||||||
|
renderHeaderCell: () => {
|
||||||
|
return 'Actions';
|
||||||
|
},
|
||||||
|
renderCell: (item) => {
|
||||||
|
return (
|
||||||
|
<TableCellLayout>
|
||||||
|
</TableCellLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
export const Models: FC = () => {
|
export const Models: FC = () => {
|
||||||
|
useEffect(() => {
|
||||||
|
fetch('https://cdn.jsdelivr.net/gh/josstorer/RWKV-Runner/manifest.json')
|
||||||
|
.then(
|
||||||
|
res => res.json().then(console.log)
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col box-border gap-5 p-2">
|
<div className="flex flex-col box-border gap-5 p-2">
|
||||||
<Text size={600}>In Development</Text>
|
<Text size={600}>In Development</Text>
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<Text weight="medium">Model Source Url List</Text>
|
||||||
|
<ToolTipButton desc="Refresh" icon={<ArrowClockwise20Regular/>}/>
|
||||||
|
</div>
|
||||||
|
<Text size={100}>description</Text>
|
||||||
|
<Textarea size="large" resize="vertical"
|
||||||
|
defaultValue="https://cdn.jsdelivr.net/gh/josstorer/RWKV-Runner/manifest.json;"/>
|
||||||
|
</div>
|
||||||
|
<DataGrid
|
||||||
|
items={items}
|
||||||
|
columns={columns}
|
||||||
|
sortable={true}
|
||||||
|
>
|
||||||
|
<DataGridHeader>
|
||||||
|
<DataGridRow>
|
||||||
|
{({renderHeaderCell}) => (
|
||||||
|
<DataGridHeaderCell>{renderHeaderCell()}</DataGridHeaderCell>
|
||||||
|
)}
|
||||||
|
</DataGridRow>
|
||||||
|
</DataGridHeader>
|
||||||
|
<DataGridBody<Item>>
|
||||||
|
{({item, rowId}) => (
|
||||||
|
<DataGridRow<Item> key={rowId}>
|
||||||
|
{({renderCell}) => (
|
||||||
|
<DataGridCell>{renderCell(item)}</DataGridCell>
|
||||||
|
)}
|
||||||
|
</DataGridRow>
|
||||||
|
)}
|
||||||
|
</DataGridBody>
|
||||||
|
</DataGrid>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,12 +3,12 @@ import {Label, Tooltip} from '@fluentui/react-components';
|
|||||||
|
|
||||||
export const Labeled: FC<{ label: string; desc?: string, content: ReactElement }> = ({label, desc, content}) => {
|
export const Labeled: FC<{ label: string; desc?: string, content: ReactElement }> = ({label, desc, content}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center">
|
<div className="grid grid-cols-2 items-center">
|
||||||
{desc ?
|
{desc ?
|
||||||
<Tooltip content={desc} showDelay={0} hideDelay={0} relationship="description">
|
<Tooltip content={desc} showDelay={0} hideDelay={0} relationship="description">
|
||||||
<Label className="w-44">{label}</Label>
|
<Label>{label}</Label>
|
||||||
</Tooltip> :
|
</Tooltip> :
|
||||||
<Label className="w-44">{label}</Label>
|
<Label>{label}</Label>
|
||||||
}
|
}
|
||||||
{content}
|
{content}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
import {FC, ReactElement} from 'react';
|
import {FC, ReactElement} from 'react';
|
||||||
import {Text} from '@fluentui/react-components';
|
import {Card, Text} from '@fluentui/react-components';
|
||||||
|
|
||||||
export const Section: FC<{ title: string; desc?: string, content: ReactElement }> = ({title, desc, content}) => {
|
export const Section: FC<{
|
||||||
return (
|
title: string; desc?: string, content: ReactElement, outline?: boolean
|
||||||
<div className="flex flex-col gap-5">
|
}> =
|
||||||
<div className="flex flex-col gap-1">
|
({title, desc, content, outline = true}) => {
|
||||||
<Text weight="medium">{title}</Text>
|
return (
|
||||||
{desc && <Text size={100}>{desc}</Text>}
|
<Card size="small" appearance={outline ? 'outline' : 'subtle'}>
|
||||||
</div>
|
<div className="flex flex-col gap-5">
|
||||||
{content}
|
<div className="flex flex-col gap-1">
|
||||||
</div>
|
<Text weight="medium">{title}</Text>
|
||||||
);
|
{desc && <Text size={100}>{desc}</Text>}
|
||||||
};
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="overflow-y-auto overflow-x-hidden p-1">
|
||||||
|
{content}
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@ -3,6 +3,25 @@
|
|||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
scrollbar-width: thin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Works on Chrome, Edge, and Safari */
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
width: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-thumb {
|
||||||
|
background-color: rgba(155, 155, 155, 0.5);
|
||||||
|
border-radius: 20px;
|
||||||
|
border: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
2
frontend/wailsjs/go/backend_golang/App.d.ts
vendored
2
frontend/wailsjs/go/backend_golang/App.d.ts
vendored
@ -1,4 +1,4 @@
|
|||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
export function SaveConfig(arg1:any):Promise<string>;
|
export function SaveJson(arg1:string,arg2:any):Promise<string>;
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
export function SaveConfig(arg1) {
|
export function SaveJson(arg1, arg2) {
|
||||||
return window['go']['backend_golang']['App']['SaveConfig'](arg1);
|
return window['go']['backend_golang']['App']['SaveJson'](arg1, arg2);
|
||||||
}
|
}
|
||||||
|
2
main.go
2
main.go
@ -22,7 +22,7 @@ func main() {
|
|||||||
Title: "RWKV-Runner",
|
Title: "RWKV-Runner",
|
||||||
Width: 1024,
|
Width: 1024,
|
||||||
Height: 640,
|
Height: 640,
|
||||||
MinWidth: 1024,
|
MinWidth: 375,
|
||||||
MinHeight: 640,
|
MinHeight: 640,
|
||||||
AssetServer: &assetserver.Options{
|
AssetServer: &assetserver.Options{
|
||||||
Assets: assets,
|
Assets: assets,
|
||||||
|
17
manifest.json
Normal file
17
manifest.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0.0",
|
||||||
|
"models": [
|
||||||
|
{
|
||||||
|
"name": "RWKV-4-Raven-14B-v11x-Eng99%-Other1%-20230501-ctx8192.pth",
|
||||||
|
"desc": {
|
||||||
|
"en": "Mainly English language corpus",
|
||||||
|
"zh": "英语语料为主"
|
||||||
|
},
|
||||||
|
"size": 28297309490,
|
||||||
|
"lastUpdated": "2023-05-02T09:43:33",
|
||||||
|
"url": "https://huggingface.co/BlinkDL/rwkv-4-raven/blob/main/RWKV-4-Raven-14B-v11x-Eng99%25-Other1%25-20230501-ctx8192.pth",
|
||||||
|
"downloadUrl": "https://huggingface.co/BlinkDL/rwkv-4-raven/resolve/main/RWKV-4-Raven-14B-v11x-Eng99%25-Other1%25-20230501-ctx8192.pth",
|
||||||
|
"SHA256": "c4bc72406c3c62613e8e2592e8d07ac045f8a88381c728f8eb60af890e299f4d"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user