improve python script error messages
This commit is contained in:
parent
2d545604f4
commit
6fbb86667c
@ -113,3 +113,11 @@ func (a *App) InstallPyDep(python string, cnMirror bool) (string, error) {
|
|||||||
return Cmd(python, "-m", "pip", "install", "-r", "./backend-python/requirements_without_cyac.txt")
|
return Cmd(python, "-m", "pip", "install", "-r", "./backend-python/requirements_without_cyac.txt")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) GetPyError() string {
|
||||||
|
content, err := os.ReadFile("./error.txt")
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(content)
|
||||||
|
}
|
||||||
|
12
backend-python/convert_model.py
vendored
12
backend-python/convert_model.py
vendored
@ -219,13 +219,17 @@ def get_args():
|
|||||||
return p.parse_args()
|
return p.parse_args()
|
||||||
|
|
||||||
|
|
||||||
args = get_args()
|
try:
|
||||||
if not args.quiet:
|
args = get_args()
|
||||||
|
if not args.quiet:
|
||||||
print(f"** {args}")
|
print(f"** {args}")
|
||||||
|
|
||||||
RWKV(
|
RWKV(
|
||||||
getattr(args, "in"),
|
getattr(args, "in"),
|
||||||
args.strategy,
|
args.strategy,
|
||||||
verbose=not args.quiet,
|
verbose=not args.quiet,
|
||||||
convert_and_save_and_exit=args.out,
|
convert_and_save_and_exit=args.out,
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
with open("error.txt", "w") as f:
|
||||||
|
f.write(str(e))
|
||||||
|
@ -243,4 +243,8 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
main()
|
main()
|
||||||
|
except Exception as e:
|
||||||
|
with open("error.txt", "w") as f:
|
||||||
|
f.write(str(e))
|
||||||
|
55
finetune/lora/merge_lora.py
vendored
55
finetune/lora/merge_lora.py
vendored
@ -5,49 +5,64 @@ from typing import Dict
|
|||||||
import typing
|
import typing
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
if '-h' in sys.argv or '--help' in sys.argv:
|
try:
|
||||||
print(f'Usage: python3 {sys.argv[0]} [--use-gpu] <lora_alpha> <base_model.pth> <lora_checkpoint.pth> <output.pth>')
|
if "-h" in sys.argv or "--help" in sys.argv:
|
||||||
|
print(
|
||||||
|
f"Usage: python3 {sys.argv[0]} [--use-gpu] <lora_alpha> <base_model.pth> <lora_checkpoint.pth> <output.pth>"
|
||||||
|
)
|
||||||
|
|
||||||
if sys.argv[1] == '--use-gpu':
|
if sys.argv[1] == "--use-gpu":
|
||||||
device = 'cuda'
|
device = "cuda"
|
||||||
lora_alpha, base_model, lora, output = float(sys.argv[2]), sys.argv[3], sys.argv[4], sys.argv[5]
|
lora_alpha, base_model, lora, output = (
|
||||||
else:
|
float(sys.argv[2]),
|
||||||
device = 'cpu'
|
sys.argv[3],
|
||||||
lora_alpha, base_model, lora, output = float(sys.argv[1]), sys.argv[2], sys.argv[3], sys.argv[4]
|
sys.argv[4],
|
||||||
|
sys.argv[5],
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
device = "cpu"
|
||||||
|
lora_alpha, base_model, lora, output = (
|
||||||
|
float(sys.argv[1]),
|
||||||
|
sys.argv[2],
|
||||||
|
sys.argv[3],
|
||||||
|
sys.argv[4],
|
||||||
|
)
|
||||||
|
|
||||||
|
with torch.no_grad():
|
||||||
with torch.no_grad():
|
w: Dict[str, torch.Tensor] = torch.load(base_model, map_location="cpu")
|
||||||
w: Dict[str, torch.Tensor] = torch.load(base_model, map_location='cpu')
|
|
||||||
# merge LoRA-only slim checkpoint into the main weights
|
# merge LoRA-only slim checkpoint into the main weights
|
||||||
w_lora: Dict[str, torch.Tensor] = torch.load(lora, map_location='cpu')
|
w_lora: Dict[str, torch.Tensor] = torch.load(lora, map_location="cpu")
|
||||||
for k in w_lora.keys():
|
for k in w_lora.keys():
|
||||||
w[k] = w_lora[k]
|
w[k] = w_lora[k]
|
||||||
output_w: typing.OrderedDict[str, torch.Tensor] = OrderedDict()
|
output_w: typing.OrderedDict[str, torch.Tensor] = OrderedDict()
|
||||||
# merge LoRA weights
|
# merge LoRA weights
|
||||||
keys = list(w.keys())
|
keys = list(w.keys())
|
||||||
for k in keys:
|
for k in keys:
|
||||||
if k.endswith('.weight'):
|
if k.endswith(".weight"):
|
||||||
prefix = k[:-len('.weight')]
|
prefix = k[: -len(".weight")]
|
||||||
lora_A = prefix + '.lora_A'
|
lora_A = prefix + ".lora_A"
|
||||||
lora_B = prefix + '.lora_B'
|
lora_B = prefix + ".lora_B"
|
||||||
if lora_A in keys:
|
if lora_A in keys:
|
||||||
assert lora_B in keys
|
assert lora_B in keys
|
||||||
print(f'merging {lora_A} and {lora_B} into {k}')
|
print(f"merging {lora_A} and {lora_B} into {k}")
|
||||||
assert w[lora_B].shape[1] == w[lora_A].shape[0]
|
assert w[lora_B].shape[1] == w[lora_A].shape[0]
|
||||||
lora_r = w[lora_B].shape[1]
|
lora_r = w[lora_B].shape[1]
|
||||||
w[k] = w[k].to(device=device)
|
w[k] = w[k].to(device=device)
|
||||||
w[lora_A] = w[lora_A].to(device=device)
|
w[lora_A] = w[lora_A].to(device=device)
|
||||||
w[lora_B] = w[lora_B].to(device=device)
|
w[lora_B] = w[lora_B].to(device=device)
|
||||||
w[k] += w[lora_B] @ w[lora_A] * (lora_alpha / lora_r)
|
w[k] += w[lora_B] @ w[lora_A] * (lora_alpha / lora_r)
|
||||||
output_w[k] = w[k].to(device='cpu', copy=True)
|
output_w[k] = w[k].to(device="cpu", copy=True)
|
||||||
del w[k]
|
del w[k]
|
||||||
del w[lora_A]
|
del w[lora_A]
|
||||||
del w[lora_B]
|
del w[lora_B]
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if 'lora' not in k:
|
if "lora" not in k:
|
||||||
print(f'retaining {k}')
|
print(f"retaining {k}")
|
||||||
output_w[k] = w[k].clone()
|
output_w[k] = w[k].clone()
|
||||||
del w[k]
|
del w[k]
|
||||||
|
|
||||||
torch.save(output_w, output)
|
torch.save(output_w, output)
|
||||||
|
except Exception as e:
|
||||||
|
with open("error.txt", "w") as f:
|
||||||
|
f.write(str(e))
|
||||||
|
@ -229,5 +229,7 @@
|
|||||||
"VRAM is not enough": "显存不足",
|
"VRAM is not enough": "显存不足",
|
||||||
"Training data is not enough, reduce context length or add more data for training": "训练数据不足,请减小上下文长度或增加训练数据",
|
"Training data is not enough, reduce context length or add more data for training": "训练数据不足,请减小上下文长度或增加训练数据",
|
||||||
"You are using WSL 1 for training, please upgrade to WSL 2. e.g. Run \"wsl --set-version Ubuntu-22.04 2\"": "你正在使用WSL 1进行训练,请升级到WSL 2。例如,运行\"wsl --set-version Ubuntu-22.04 2\"",
|
"You are using WSL 1 for training, please upgrade to WSL 2. e.g. Run \"wsl --set-version Ubuntu-22.04 2\"": "你正在使用WSL 1进行训练,请升级到WSL 2。例如,运行\"wsl --set-version Ubuntu-22.04 2\"",
|
||||||
"Matched CUDA is not installed": "未安装匹配的CUDA"
|
"Matched CUDA is not installed": "未安装匹配的CUDA",
|
||||||
|
"Failed to convert data": "数据转换失败",
|
||||||
|
"Failed to merge model": "合并模型失败"
|
||||||
}
|
}
|
@ -13,8 +13,8 @@ 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';
|
import { updateConfig } from '../apis';
|
||||||
import { ConvertModel, FileExists } from '../../wailsjs/go/backend_golang/App';
|
import { ConvertModel, FileExists, GetPyError } from '../../wailsjs/go/backend_golang/App';
|
||||||
import { getStrategy, refreshLocalModels } from '../utils';
|
import { getStrategy } from '../utils';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { WindowShow } from '../../wailsjs/runtime/runtime';
|
import { WindowShow } from '../../wailsjs/runtime/runtime';
|
||||||
import strategyImg from '../assets/images/strategy.jpg';
|
import strategyImg from '../assets/images/strategy.jpg';
|
||||||
@ -253,9 +253,12 @@ export const Configs: FC = observer(() => {
|
|||||||
const strategy = getStrategy(selectedConfig);
|
const strategy = getStrategy(selectedConfig);
|
||||||
const newModelPath = modelPath + '-' + strategy.replace(/[:> *+]/g, '-');
|
const newModelPath = modelPath + '-' + strategy.replace(/[:> *+]/g, '-');
|
||||||
toast(t('Start Converting'), { autoClose: 1000, type: 'info' });
|
toast(t('Start Converting'), { autoClose: 1000, type: 'info' });
|
||||||
ConvertModel(commonStore.settings.customPythonPath, modelPath, strategy, newModelPath).then(() => {
|
ConvertModel(commonStore.settings.customPythonPath, modelPath, strategy, newModelPath).then(async () => {
|
||||||
|
if (!await FileExists(newModelPath)) {
|
||||||
|
toast(t('Convert Failed') + ' - ' + await GetPyError(), { type: 'error' });
|
||||||
|
} else {
|
||||||
toast(`${t('Convert Success')} - ${newModelPath}`, { type: 'success' });
|
toast(`${t('Convert Success')} - ${newModelPath}`, { type: 'success' });
|
||||||
refreshLocalModels({ models: commonStore.modelSourceList }, false);
|
}
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
const errMsg = e.message || e;
|
const errMsg = e.message || e;
|
||||||
if (errMsg.includes('path contains space'))
|
if (errMsg.includes('path contains space'))
|
||||||
|
@ -4,6 +4,7 @@ import { Button, Dropdown, Input, Option, Select, Switch, Tab, TabList } from '@
|
|||||||
import {
|
import {
|
||||||
ConvertData,
|
ConvertData,
|
||||||
FileExists,
|
FileExists,
|
||||||
|
GetPyError,
|
||||||
MergeLora,
|
MergeLora,
|
||||||
OpenFileFolder,
|
OpenFileFolder,
|
||||||
WslCommand,
|
WslCommand,
|
||||||
@ -17,7 +18,7 @@ import { toast } from 'react-toastify';
|
|||||||
import commonStore from '../stores/commonStore';
|
import commonStore from '../stores/commonStore';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
import { SelectTabEventHandler } from '@fluentui/react-tabs';
|
import { SelectTabEventHandler } from '@fluentui/react-tabs';
|
||||||
import { checkDependencies, refreshLocalModels, toastWithButton } from '../utils';
|
import { checkDependencies, toastWithButton } from '../utils';
|
||||||
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';
|
||||||
@ -421,10 +422,13 @@ const LoraFinetune: FC = observer(() => {
|
|||||||
const ok = await checkDependencies(navigate);
|
const ok = await checkDependencies(navigate);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return;
|
return;
|
||||||
ConvertData(commonStore.settings.customPythonPath, dataParams.dataPath,
|
const outputPrefix = './finetune/json2binidx_tool/data/' + dataParams.dataPath.split(/[\/\\]/).pop()!.split('.')[0];
|
||||||
'./finetune/json2binidx_tool/data/' + dataParams.dataPath.split(/[\/\\]/).pop()!.split('.')[0],
|
ConvertData(commonStore.settings.customPythonPath, dataParams.dataPath, outputPrefix, dataParams.vocabPath).then(async () => {
|
||||||
dataParams.vocabPath).then(() => {
|
if (!await FileExists(outputPrefix + '_text_document.idx')) {
|
||||||
|
toast(t('Failed to convert data') + ' - ' + await GetPyError(), { type: 'error' });
|
||||||
|
} else {
|
||||||
toast(t('Convert Data successfully'), { type: 'success' });
|
toast(t('Convert Data successfully'), { type: 'success' });
|
||||||
|
}
|
||||||
}).catch(showError);
|
}).catch(showError);
|
||||||
}}>{t('Convert')}</Button>
|
}}>{t('Convert')}</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -472,11 +476,15 @@ const LoraFinetune: FC = observer(() => {
|
|||||||
if (!ok)
|
if (!ok)
|
||||||
return;
|
return;
|
||||||
if (loraParams.loraLoad) {
|
if (loraParams.loraLoad) {
|
||||||
|
const outputPath = `models/${loraParams.baseModel}-LoRA-${loraParams.loraLoad}`;
|
||||||
MergeLora(commonStore.settings.customPythonPath, true, loraParams.loraAlpha,
|
MergeLora(commonStore.settings.customPythonPath, true, loraParams.loraAlpha,
|
||||||
'models/' + loraParams.baseModel, 'lora-models/' + loraParams.loraLoad,
|
'models/' + loraParams.baseModel, 'lora-models/' + loraParams.loraLoad,
|
||||||
`models/${loraParams.baseModel}-LoRA-${loraParams.loraLoad}`).then(() => {
|
outputPath).then(async () => {
|
||||||
|
if (!await FileExists(outputPath)) {
|
||||||
|
toast(t('Failed to merge model') + ' - ' + await GetPyError(), { type: 'error' });
|
||||||
|
} else {
|
||||||
toast(t('Merge model successfully'), { type: 'success' });
|
toast(t('Merge model successfully'), { type: 'success' });
|
||||||
refreshLocalModels({ models: commonStore.modelSourceList }, false);
|
}
|
||||||
}).catch(showError);
|
}).catch(showError);
|
||||||
} else {
|
} else {
|
||||||
toast(t('Please select a LoRA model'), { type: 'info' });
|
toast(t('Please select a LoRA model'), { type: 'info' });
|
||||||
|
2
frontend/wailsjs/go/backend_golang/App.d.ts
generated
vendored
2
frontend/wailsjs/go/backend_golang/App.d.ts
generated
vendored
@ -22,6 +22,8 @@ export function FileExists(arg1:string):Promise<boolean>;
|
|||||||
|
|
||||||
export function GetPlatform():Promise<string>;
|
export function GetPlatform():Promise<string>;
|
||||||
|
|
||||||
|
export function GetPyError():Promise<string>;
|
||||||
|
|
||||||
export function InstallPyDep(arg1:string,arg2:boolean):Promise<string>;
|
export function InstallPyDep(arg1:string,arg2:boolean):Promise<string>;
|
||||||
|
|
||||||
export function ListDirFiles(arg1:string):Promise<Array<backend_golang.FileInfo>>;
|
export function ListDirFiles(arg1:string):Promise<Array<backend_golang.FileInfo>>;
|
||||||
|
4
frontend/wailsjs/go/backend_golang/App.js
generated
4
frontend/wailsjs/go/backend_golang/App.js
generated
@ -42,6 +42,10 @@ export function GetPlatform() {
|
|||||||
return window['go']['backend_golang']['App']['GetPlatform']();
|
return window['go']['backend_golang']['App']['GetPlatform']();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function GetPyError() {
|
||||||
|
return window['go']['backend_golang']['App']['GetPyError']();
|
||||||
|
}
|
||||||
|
|
||||||
export function InstallPyDep(arg1, arg2) {
|
export function InstallPyDep(arg1, arg2) {
|
||||||
return window['go']['backend_golang']['App']['InstallPyDep'](arg1, arg2);
|
return window['go']['backend_golang']['App']['InstallPyDep'](arg1, arg2);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user