preliminary usable features

This commit is contained in:
josc146 2023-05-17 11:39:00 +08:00
parent 53502a8c3d
commit c947052574
21 changed files with 1187 additions and 1080 deletions

7
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
},
"python.formatting.provider": "black",
"editor.formatOnSave": true
}

View File

@ -2,10 +2,16 @@ package backend_golang
import ( import (
"os/exec" "os/exec"
"path/filepath"
"strconv"
) )
func (a *App) StartServer(strategy string, modelPath string) (string, error) { func (a *App) StartServer(port int) (string, error) {
cmd := exec.Command("cmd-helper", "python", "./backend-python/main.py", strategy, modelPath) cmdHelper, err := filepath.Abs("./cmd-helper")
if err != nil {
return "", err
}
cmd := exec.Command(cmdHelper, "python", "./backend-python/main.py", strconv.Itoa(port))
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return "", err return "", err

View File

@ -1,7 +1,8 @@
from enum import Enum, auto from enum import Enum, auto
Model = 'model' Model = "model"
Model_Status = 'model_status' Model_Status = "model_status"
Model_Config = "model_config"
class ModelStatus(Enum): class ModelStatus(Enum):

View File

@ -1,5 +1,6 @@
import os import os
import psutil import psutil
import sys
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
@ -26,7 +27,7 @@ app.include_router(completion.router)
app.include_router(config.router) app.include_router(config.router)
@app.on_event('startup') @app.on_event("startup")
def init(): def init():
global_var.init() global_var.init()
@ -38,7 +39,7 @@ def init():
@app.get("/") @app.get("/")
def read_root(): def read_root():
return {"Hello": "World!"} return {"Hello": "World!", "pid": os.getpid()}
@app.post("/exit") @app.post("/exit")
@ -51,4 +52,4 @@ def exit():
if __name__ == "__main__": if __name__ == "__main__":
uvicorn.run("main:app", port=8000) uvicorn.run("main:app", port=8000 if len(sys.argv) == 1 else int(sys.argv[1]))

View File

@ -1,4 +1,6 @@
import asyncio
import json import json
from threading import Lock
from typing import List from typing import List
from fastapi import APIRouter, Request, status, HTTPException from fastapi import APIRouter, Request, status, HTTPException
@ -15,46 +17,99 @@ class Message(BaseModel):
content: str content: str
class CompletionBody(BaseModel): class CompletionBody(ModelConfigBody):
messages: List[Message] messages: List[Message]
model: str model: str
stream: bool stream: bool
max_tokens: int
completion_lock = Lock()
@router.post("/v1/chat/completions") @router.post("/v1/chat/completions")
@router.post("/chat/completions") @router.post("/chat/completions")
async def completions(body: CompletionBody, request: Request): async def completions(body: CompletionBody, request: Request):
model = global_var.get(global_var.Model) model: RWKV = global_var.get(global_var.Model)
if (model is None): if model is None:
raise HTTPException(status.HTTP_400_BAD_REQUEST, "model not loaded") raise HTTPException(status.HTTP_400_BAD_REQUEST, "model not loaded")
question = body.messages[-1] question = body.messages[-1]
if question.role == 'user': if question.role == "user":
question = question.content question = question.content
else: else:
raise HTTPException(status.HTTP_400_BAD_REQUEST, "no question found") raise HTTPException(status.HTTP_400_BAD_REQUEST, "no question found")
completion_text = "" completion_text = ""
for message in body.messages: for message in body.messages:
if message.role == 'user': if message.role == "user":
completion_text += "Bob: " + message.content + "\n\n" completion_text += "Bob: " + message.content + "\n\n"
elif message.role == 'assistant': elif message.role == "assistant":
completion_text += "Alice: " + message.content + "\n\n" completion_text += "Alice: " + message.content + "\n\n"
completion_text += "Alice:" completion_text += "Alice:"
async def eval_rwkv(): async def eval_rwkv():
if body.stream: while completion_lock.locked():
for response, delta in rwkv_generate(model, completion_text, stop="Bob:"): await asyncio.sleep(0.1)
if await request.is_disconnected():
break
yield json.dumps({"response": response, "choices": [{"delta": {"content": delta}}], "model": "rwkv"})
yield "[DONE]"
else: else:
response = None with completion_lock:
for response, delta in rwkv_generate(model, completion_text, stop="Bob:"): set_rwkv_config(model, global_var.get(global_var.Model_Config))
pass set_rwkv_config(model, body)
yield json.dumps({"response": response, "model": "rwkv"}) if body.stream:
# torch_gc() for response, delta in rwkv_generate(
model, completion_text, stop="Bob:"
):
if await request.is_disconnected():
break
yield json.dumps(
{
"response": response,
"model": "rwkv",
"choices": [
{
"delta": {"content": delta},
"index": 0,
"finish_reason": None,
}
],
}
)
yield json.dumps(
{
"response": response,
"model": "rwkv",
"choices": [
{
"delta": {},
"index": 0,
"finish_reason": "stop",
}
],
}
)
yield "[DONE]"
else:
response = None
for response, delta in rwkv_generate(
model, completion_text, stop="Bob:"
):
pass
yield {
"response": response,
"model": "rwkv",
"choices": [
{
"message": {
"role": "assistant",
"content": response,
},
"index": 0,
"finish_reason": "stop",
}
],
}
# torch_gc()
return EventSourceResponse(eval_rwkv()) if body.stream:
return EventSourceResponse(eval_rwkv())
else:
return await eval_rwkv().__anext__()

View File

@ -1,5 +1,4 @@
import pathlib import pathlib
import sys
from fastapi import APIRouter, HTTPException, Response, status from fastapi import APIRouter, HTTPException, Response, status
from pydantic import BaseModel from pydantic import BaseModel
@ -11,19 +10,14 @@ import global_var
router = APIRouter() router = APIRouter()
class UpdateConfigBody(BaseModel): class SwitchModelBody(BaseModel):
model: str = None model: str
strategy: str = None strategy: str
max_response_token: int = None
temperature: float = None
top_p: float = None
presence_penalty: float = None
count_penalty: float = None
@router.post("/update-config") @router.post("/switch-model")
def update_config(body: UpdateConfigBody, response: Response): def switch_model(body: SwitchModelBody, response: Response):
if (global_var.get(global_var.Model_Status) is global_var.ModelStatus.Loading): if global_var.get(global_var.Model_Status) is global_var.ModelStatus.Loading:
response.status_code = status.HTTP_304_NOT_MODIFIED response.status_code = status.HTTP_304_NOT_MODIFIED
return return
@ -33,15 +27,34 @@ def update_config(body: UpdateConfigBody, response: Response):
global_var.set(global_var.Model_Status, global_var.ModelStatus.Loading) global_var.set(global_var.Model_Status, global_var.ModelStatus.Loading)
try: try:
global_var.set(global_var.Model, RWKV( global_var.set(
model=sys.argv[2], global_var.Model,
strategy=sys.argv[1], RWKV(
tokens_path=f"{pathlib.Path(__file__).parent.parent.resolve()}/20B_tokenizer.json" model=body.model,
)) strategy=body.strategy,
tokens_path=f"{pathlib.Path(__file__).parent.parent.resolve()}/20B_tokenizer.json",
),
)
except Exception: except Exception:
global_var.set(global_var.Model_Status, global_var.ModelStatus.Offline) global_var.set(global_var.Model_Status, global_var.ModelStatus.Offline)
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to load") raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to load")
if global_var.get(global_var.Model_Config) is None:
global_var.set(
global_var.Model_Config, get_rwkv_config(global_var.get(global_var.Model))
)
global_var.set(global_var.Model_Status, global_var.ModelStatus.Working) global_var.set(global_var.Model_Status, global_var.ModelStatus.Working)
return "success" return "success"
@router.post("/update-config")
def update_config(body: ModelConfigBody):
"""
Will not update the model config immediately, but set it when completion called to avoid modifications during generation
"""
print(body)
global_var.set(global_var.Model_Config, body)
return "success"

View File

@ -3,6 +3,7 @@ import os
def ngrok_connect(): def ngrok_connect():
from pyngrok import ngrok, conf from pyngrok import ngrok, conf
conf.set_default(conf.PyngrokConfig(ngrok_path="./ngrok")) conf.set_default(conf.PyngrokConfig(ngrok_path="./ngrok"))
ngrok.set_auth_token(os.environ["ngrok_token"]) ngrok.set_auth_token(os.environ["ngrok_token"])
http_tunnel = ngrok.connect(8000) http_tunnel = ngrok.connect(8000)

View File

@ -1,5 +1,37 @@
from typing import Dict from typing import Dict
from langchain.llms import RWKV from langchain.llms import RWKV
from pydantic import BaseModel
class ModelConfigBody(BaseModel):
max_tokens: int = None
temperature: float = None
top_p: float = None
presence_penalty: float = None
frequency_penalty: float = None
def set_rwkv_config(model: RWKV, body: ModelConfigBody):
if body.max_tokens:
model.max_tokens_per_generation = body.max_tokens
if body.temperature:
model.temperature = body.temperature
if body.top_p:
model.top_p = body.top_p
if body.presence_penalty:
model.penalty_alpha_presence = body.presence_penalty
if body.frequency_penalty:
model.penalty_alpha_frequency = body.frequency_penalty
def get_rwkv_config(model: RWKV) -> ModelConfigBody:
return ModelConfigBody(
max_tokens=model.max_tokens_per_generation,
temperature=model.temperature,
top_p=model.top_p,
presence_penalty=model.penalty_alpha_presence,
frequency_penalty=model.penalty_alpha_frequency,
)
def rwkv_generate(model: RWKV, prompt: str, stop: str = None): def rwkv_generate(model: RWKV, prompt: str, stop: str = None):

View File

@ -11,8 +11,8 @@ def set_torch():
print("torch already set") print("torch already set")
else: else:
print("run:") print("run:")
os.environ['PATH'] = paths + os.pathsep + torch_path + os.pathsep os.environ["PATH"] = paths + os.pathsep + torch_path + os.pathsep
print(f'set Path={paths + os.pathsep + torch_path + os.pathsep}') print(f"set Path={paths + os.pathsep + torch_path + os.pathsep}")
else: else:
print("torch not found") print("torch not found")

File diff suppressed because it is too large Load Diff

View File

@ -9,26 +9,26 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@fluentui/react-components": "^9.19.1", "@fluentui/react-components": "^9.20.0",
"@fluentui/react-icons": "^2.0.201", "@fluentui/react-icons": "^2.0.201",
"mobx": "^6.9.0", "mobx": "^6.9.0",
"mobx-react-lite": "^3.4.3", "mobx-react-lite": "^3.4.3",
"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.1",
"react-router-dom": "^6.11.0", "react-router-dom": "^6.11.1",
"react-toastify": "^9.1.2", "react-toastify": "^9.1.3",
"usehooks-ts": "^2.9.1" "usehooks-ts": "^2.9.1"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.0.17", "@types/react": "^18.2.6",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.2.4",
"@vitejs/plugin-react": "^2.0.1", "@vitejs/plugin-react": "^4.0.0",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"postcss": "^8.4.23", "postcss": "^8.4.23",
"rollup-plugin-visualizer": "^5.9.0", "rollup-plugin-visualizer": "^5.9.0",
"tailwindcss": "^3.3.2", "tailwindcss": "^3.3.2",
"typescript": "^4.6.4", "typescript": "^5.0.4",
"vite": "^3.0.7" "vite": "^4.3.6"
} }
} }

View File

@ -85,8 +85,9 @@ const App: FC = () => {
style={{ style={{
width: '250px' width: '250px'
}} }}
position="top-right" position="top-center"
autoClose={4000} autoClose={4000}
hideProgressBar={true}
newestOnTop={true} newestOnTop={true}
closeOnClick={false} closeOnClick={false}
rtl={false} rtl={false}

View File

@ -0,0 +1,34 @@
import commonStore, {ModelStatus} from '../stores/commonStore';
export const readRoot = async () => {
const port = commonStore.getCurrentModelConfig().apiParameters.apiPort;
return fetch(`http://127.0.0.1:${port}`);
};
export const exit = async () => {
commonStore.setModelStatus(ModelStatus.Offline);
const port = commonStore.getCurrentModelConfig().apiParameters.apiPort;
return fetch(`http://127.0.0.1:${port}/exit`, {method: 'POST'});
};
export const switchModel = async (body: any) => {
const port = commonStore.getCurrentModelConfig().apiParameters.apiPort;
return fetch(`http://127.0.0.1:${port}/switch-model`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
};
export const updateConfig = async (body: any) => {
const port = commonStore.getCurrentModelConfig().apiParameters.apiPort;
return fetch(`http://127.0.0.1:${port}/update-config`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
};

View File

@ -1,8 +1,10 @@
import React, {FC} from 'react'; import React, {FC, MouseEventHandler} from 'react';
import commonStore, {ModelStatus} from '../stores/commonStore'; import commonStore, {ModelStatus} from '../stores/commonStore';
import {StartServer} from '../../wailsjs/go/backend_golang/App'; import {StartServer} from '../../wailsjs/go/backend_golang/App';
import {Button} from '@fluentui/react-components'; import {Button} from '@fluentui/react-components';
import {observer} from 'mobx-react-lite'; import {observer} from 'mobx-react-lite';
import {exit, readRoot, switchModel, updateConfig} from '../apis';
import {toast} from 'react-toastify';
const mainButtonText = { const mainButtonText = {
[ModelStatus.Offline]: 'Run', [ModelStatus.Offline]: 'Run',
@ -12,28 +14,42 @@ const mainButtonText = {
}; };
const onClickMainButton = async () => { const onClickMainButton = async () => {
const modelConfig = commonStore.getCurrentModelConfig();
const port = modelConfig.apiParameters.apiPort;
if (commonStore.modelStatus === ModelStatus.Offline) { if (commonStore.modelStatus === ModelStatus.Offline) {
commonStore.setModelStatus(ModelStatus.Starting); commonStore.setModelStatus(ModelStatus.Starting);
StartServer(commonStore.getStrategy(), `models\\${commonStore.getCurrentModelConfig().modelParameters.modelName}`); StartServer(port);
let timeoutCount = 5; let timeoutCount = 6;
let loading = false; let loading = false;
const intervalId = setInterval(() => { const intervalId = setInterval(() => {
fetch('http://127.0.0.1:8000') readRoot()
.then(r => { .then(r => {
if (r.ok && !loading) { if (r.ok && !loading) {
clearInterval(intervalId); clearInterval(intervalId);
commonStore.setModelStatus(ModelStatus.Loading); commonStore.setModelStatus(ModelStatus.Loading);
loading = true; loading = true;
fetch('http://127.0.0.1:8000/update-config', { toast('Loading Model', {type: 'info'});
method: 'POST', updateConfig({
headers: { max_tokens: modelConfig.apiParameters.maxResponseToken,
'Content-Type': 'application/json' temperature: modelConfig.apiParameters.temperature,
}, top_p: modelConfig.apiParameters.topP,
body: JSON.stringify({}) presence_penalty: modelConfig.apiParameters.presencePenalty,
}).then(async (r) => { frequency_penalty: modelConfig.apiParameters.frequencyPenalty
if (r.ok) });
switchModel({
model: `models\\${modelConfig.modelParameters.modelName}`,
strategy: commonStore.getStrategy(modelConfig)
}).then((r) => {
if (r.ok) {
commonStore.setModelStatus(ModelStatus.Working); commonStore.setModelStatus(ModelStatus.Working);
} else if (r.status === 304) {
toast('Loading Model', {type: 'info'});
} else {
commonStore.setModelStatus(ModelStatus.Offline);
toast('Failed to switch model', {type: 'error'});
}
}); });
} }
}).catch(() => { }).catch(() => {
@ -46,15 +62,18 @@ const onClickMainButton = async () => {
timeoutCount--; timeoutCount--;
}, 1000); }, 1000);
} else { } else {
commonStore.setModelStatus(ModelStatus.Offline); exit();
fetch('http://127.0.0.1:8000/exit', {method: 'POST'});
} }
}; };
export const RunButton: FC = observer(() => { export const RunButton: FC<{ onClickRun?: MouseEventHandler }> = observer(({onClickRun}) => {
return ( return (
<Button disabled={commonStore.modelStatus === ModelStatus.Starting} appearance="primary" size="large" <Button disabled={commonStore.modelStatus === ModelStatus.Starting} appearance="primary" size="large"
onClick={onClickMainButton}> onClick={async (e) => {
if (commonStore.modelStatus === ModelStatus.Offline)
await onClickRun?.(e);
await onClickMainButton();
}}>
{mainButtonText[commonStore.modelStatus]} {mainButtonText[commonStore.modelStatus]}
</Button> </Button>
); );

View File

@ -12,6 +12,7 @@ import {NumberInput} from '../components/NumberInput';
import {Page} from '../components/Page'; import {Page} from '../components/Page';
import {useNavigate} from 'react-router'; import {useNavigate} from 'react-router';
import {RunButton} from '../components/RunButton'; import {RunButton} from '../components/RunButton';
import {updateConfig} from '../apis';
export const Configs: FC = observer(() => { export const Configs: FC = observer(() => {
const [selectedIndex, setSelectedIndex] = React.useState(commonStore.currentModelConfigIndex); const [selectedIndex, setSelectedIndex] = React.useState(commonStore.currentModelConfigIndex);
@ -49,6 +50,18 @@ export const Configs: FC = observer(() => {
}); });
}; };
const onClickSave = () => {
commonStore.setModelConfig(selectedIndex, selectedConfig);
updateConfig({
max_tokens: selectedConfig.apiParameters.maxResponseToken,
temperature: selectedConfig.apiParameters.temperature,
top_p: selectedConfig.apiParameters.topP,
presence_penalty: selectedConfig.apiParameters.presencePenalty,
frequency_penalty: selectedConfig.apiParameters.frequencyPenalty
});
toast('Config Saved', {autoClose: 300, type: 'success'});
};
return ( return (
<Page title="Configs" content={ <Page title="Configs" content={
<div className="flex flex-col gap-2 overflow-hidden"> <div className="flex flex-col gap-2 overflow-hidden">
@ -72,10 +85,7 @@ export const Configs: FC = observer(() => {
commonStore.deleteModelConfig(selectedIndex); commonStore.deleteModelConfig(selectedIndex);
updateSelectedIndex(Math.min(selectedIndex, commonStore.modelConfigs.length - 1)); updateSelectedIndex(Math.min(selectedIndex, commonStore.modelConfigs.length - 1));
}}/> }}/>
<ToolTipButton desc="Save Config" icon={<Save20Regular/>} onClick={() => { <ToolTipButton desc="Save Config" icon={<Save20Regular/>} onClick={onClickSave}/>
commonStore.setModelConfig(selectedIndex, selectedConfig);
toast('Config Saved', {hideProgressBar: true, autoClose: 300, position: 'top-center'});
}}/>
</div> </div>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<Label>Config Name</Label> <Label>Config Name</Label>
@ -89,7 +99,7 @@ export const Configs: FC = observer(() => {
desc="Hover your mouse over the text to view a detailed description. Settings marked with * will take effect immediately after being saved." desc="Hover your mouse over the text to view a detailed description. Settings marked with * will take effect immediately after being saved."
content={ content={
<div className="grid grid-cols-1 sm:grid-cols-2 gap-2"> <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
<Labeled label="API Port" desc="127.0.0.1:8000" content={ <Labeled label="API Port" desc={`127.0.0.1:${selectedConfig.apiParameters.apiPort}`} content={
<NumberInput value={selectedConfig.apiParameters.apiPort} min={1} max={65535} step={1} <NumberInput value={selectedConfig.apiParameters.apiPort} min={1} max={65535} step={1}
onChange={(e, data) => { onChange={(e, data) => {
setSelectedConfigApiParams({ setSelectedConfigApiParams({
@ -130,11 +140,11 @@ export const Configs: FC = observer(() => {
}); });
}}/> }}/>
}/> }/>
<Labeled label="Count Penalty *" content={ <Labeled label="Frequency Penalty *" content={
<ValuedSlider value={selectedConfig.apiParameters.countPenalty} min={-2} max={2} step={0.1} input <ValuedSlider value={selectedConfig.apiParameters.frequencyPenalty} min={-2} max={2} step={0.1} input
onChange={(e, data) => { onChange={(e, data) => {
setSelectedConfigApiParams({ setSelectedConfigApiParams({
countPenalty: data.value frequencyPenalty: data.value
}); });
}}/> }}/>
}/> }/>
@ -193,12 +203,12 @@ export const Configs: FC = observer(() => {
<Option>fp32</Option> <Option>fp32</Option>
</Dropdown> </Dropdown>
}/> }/>
<Labeled label="Streamed Layers" content={ <Labeled label="Stored Layers" content={
<ValuedSlider value={selectedConfig.modelParameters.streamedLayers} min={0} <ValuedSlider value={selectedConfig.modelParameters.storedLayers} min={0}
max={selectedConfig.modelParameters.maxStreamedLayers} step={1} input max={selectedConfig.modelParameters.maxStoredLayers} step={1} input
onChange={(e, data) => { onChange={(e, data) => {
setSelectedConfigModelParams({ setSelectedConfigModelParams({
streamedLayers: data.value storedLayers: data.value
}); });
}}/> }}/>
}/> }/>
@ -215,7 +225,7 @@ export const Configs: FC = observer(() => {
/> />
</div> </div>
<div className="flex flex-row-reverse sm:fixed bottom-2 right-2"> <div className="flex flex-row-reverse sm:fixed bottom-2 right-2">
<RunButton/> <RunButton onClickRun={onClickSave}/>
</div> </div>
</div> </div>
}/> }/>

View File

@ -11,6 +11,8 @@ import {useNavigate} from 'react-router';
import commonStore from '../stores/commonStore'; import commonStore from '../stores/commonStore';
import {observer} from 'mobx-react-lite'; import {observer} from 'mobx-react-lite';
import {RunButton} from '../components/RunButton'; import {RunButton} from '../components/RunButton';
import manifest from '../../../manifest.json';
import {BrowserOpenURL} from '../../wailsjs/runtime';
type NavCard = { type NavCard = {
label: string; label: string;
@ -94,8 +96,8 @@ export const Home: FC = observer(() => {
</div> </div>
</div> </div>
<div className="flex gap-4 items-end"> <div className="flex gap-4 items-end">
Version: 1.0.0 Version: {manifest.version}
<Link>Help</Link> <Link onClick={() => BrowserOpenURL('https://github.com/josStorer/RWKV-Runner')}>Help</Link>
</div> </div>
</div> </div>
</div> </div>

View File

@ -27,7 +27,7 @@ export type ApiParameters = {
temperature: number; temperature: number;
topP: number; topP: number;
presencePenalty: number; presencePenalty: number;
countPenalty: number; frequencyPenalty: number;
} }
export type Device = 'CPU' | 'CUDA'; export type Device = 'CPU' | 'CUDA';
@ -38,8 +38,8 @@ export type ModelParameters = {
modelName: string; modelName: string;
device: Device; device: Device;
precision: Precision; precision: Precision;
streamedLayers: number; storedLayers: number;
maxStreamedLayers: number; maxStoredLayers: number;
enableHighPrecisionForLastLayer: boolean; enableHighPrecisionForLastLayer: boolean;
} }
@ -59,14 +59,14 @@ export const defaultModelConfigs: ModelConfig[] = [
temperature: 1, temperature: 1,
topP: 1, topP: 1,
presencePenalty: 0, presencePenalty: 0,
countPenalty: 0 frequencyPenalty: 0
}, },
modelParameters: { modelParameters: {
modelName: 'RWKV-4-Raven-1B5-v11-Eng99%-Other1%-20230425-ctx4096.pth', modelName: 'RWKV-4-Raven-1B5-v11-Eng99%-Other1%-20230425-ctx4096.pth',
device: 'CUDA', device: 'CUDA',
precision: 'fp16', precision: 'fp16',
streamedLayers: 25, storedLayers: 25,
maxStreamedLayers: 25, maxStoredLayers: 25,
enableHighPrecisionForLastLayer: false enableHighPrecisionForLastLayer: false
} }
} }
@ -98,8 +98,8 @@ class CommonStore {
let strategy = ''; let strategy = '';
strategy += (params.device === 'CPU' ? 'cpu' : 'cuda') + ' '; strategy += (params.device === 'CPU' ? 'cpu' : 'cuda') + ' ';
strategy += (params.precision === 'fp16' ? 'fp16' : params.precision === 'int8' ? 'fp16i8' : 'fp32'); strategy += (params.precision === 'fp16' ? 'fp16' : params.precision === 'int8' ? 'fp16i8' : 'fp32');
if (params.streamedLayers < params.maxStreamedLayers) if (params.storedLayers < params.maxStoredLayers)
strategy += ` *${params.streamedLayers}+`; strategy += ` *${params.storedLayers}+`;
if (params.enableHighPrecisionForLastLayer) if (params.enableHighPrecisionForLastLayer)
strategy += ' -> cpu fp32 *1'; strategy += ' -> cpu fp32 *1';
return strategy; return strategy;

View File

@ -16,4 +16,4 @@ export function ReadJson(arg1:string):Promise<any>;
export function SaveJson(arg1:string,arg2:any):Promise<void>; export function SaveJson(arg1:string,arg2:any):Promise<void>;
export function StartServer(arg1:string,arg2:string):Promise<string>; export function StartServer(arg1:number):Promise<string>;

View File

@ -30,6 +30,6 @@ export function SaveJson(arg1, arg2) {
return window['go']['backend_golang']['App']['SaveJson'](arg1, arg2); return window['go']['backend_golang']['App']['SaveJson'](arg1, arg2);
} }
export function StartServer(arg1, arg2) { export function StartServer(arg1) {
return window['go']['backend_golang']['App']['StartServer'](arg1, arg2); return window['go']['backend_golang']['App']['StartServer'](arg1);
} }

39
go.mod
View File

@ -1,36 +1,35 @@
module rwkv-runner module rwkv-runner
go 1.18 go 1.20
require ( require (
github.com/cavaliergopher/grab/v3 v3.0.1 github.com/cavaliergopher/grab/v3 v3.0.1
github.com/wailsapp/wails/v2 v2.4.1 github.com/wailsapp/wails/v2 v2.5.1
) )
require ( require (
github.com/bep/debounce v1.2.1 // indirect github.com/bep/debounce v1.2.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/google/uuid v1.1.2 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
github.com/labstack/echo/v4 v4.9.0 // indirect github.com/labstack/echo/v4 v4.10.2 // indirect
github.com/labstack/gommon v0.3.1 // indirect github.com/labstack/gommon v0.4.0 // indirect
github.com/leaanthony/go-ansi-parser v1.0.1 // indirect github.com/leaanthony/go-ansi-parser v1.6.0 // indirect
github.com/leaanthony/gosod v1.0.3 // indirect github.com/leaanthony/gosod v1.0.3 // indirect
github.com/leaanthony/slicer v1.5.0 // indirect github.com/leaanthony/slicer v1.6.0 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-isatty v0.0.18 // indirect
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/samber/lo v1.27.1 // indirect github.com/rivo/uniseg v0.4.4 // indirect
github.com/tkrajina/go-reflector v0.5.5 // indirect github.com/samber/lo v1.38.1 // indirect
github.com/tkrajina/go-reflector v0.5.6 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/wailsapp/mimetype v1.4.1 // indirect github.com/wailsapp/mimetype v1.4.1 // indirect
golang.org/x/crypto v0.1.0 // indirect golang.org/x/crypto v0.9.0 // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect
golang.org/x/net v0.8.0 // indirect golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.6.0 // indirect golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect
) )
// replace github.com/wailsapp/wails/v2 v2.4.1 => C:\Users\JosStorer\go\pkg\mod

71
go.sum
View File

@ -7,57 +7,64 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY= github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc= github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc=
github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA= github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA=
github.com/leaanthony/go-ansi-parser v1.0.1 h1:97v6c5kYppVsbScf4r/VZdXyQ21KQIfeQOk2DgKxGG4= github.com/leaanthony/go-ansi-parser v1.6.0 h1:T8TuMhFB6TUMIUm0oRrSbgJudTFw9csT3ZK09w0t4Pg=
github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM= github.com/leaanthony/go-ansi-parser v1.6.0/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ= github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ=
github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4= github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4=
github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY=
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY= github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js=
github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/samber/lo v1.27.1 h1:sTXwkRiIFIQG+G0HeAvOEnGjqWeWtI9cg5/n51KrxPg= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/samber/lo v1.27.1/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/tkrajina/go-reflector v0.5.6 h1:hKQ0gyocG7vgMD2M3dRlYN6WBBOmdoOzJ6njQSepKdE=
github.com/tkrajina/go-reflector v0.5.5 h1:gwoQFNye30Kk7NrExj8zm3zFtrGPqOkzFMLuQZg1DtQ= github.com/tkrajina/go-reflector v0.5.6/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
github.com/tkrajina/go-reflector v0.5.5/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
github.com/wailsapp/wails/v2 v2.4.1 h1:Ns7MOKWQM6l0ttBxpd5VcgYrH+GNPOnoDfnsBpbDnzM= github.com/wailsapp/wails/v2 v2.5.1 h1:mfG+2kWqQXYOwdgI43HEILjOZDXbk5woPYI3jP2b+js=
github.com/wailsapp/wails/v2 v2.4.1/go.mod h1:jbOZbcr/zm79PxXxAjP8UoVlDd9wLW3uDs+isIthDfs= github.com/wailsapp/wails/v2 v2.5.1/go.mod h1:jbOZbcr/zm79PxXxAjP8UoVlDd9wLW3uDs+isIthDfs=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU=
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -66,12 +73,14 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=