Fix LoRA training Error 500 - remove Radio serialization issue

The @gradio/client was wrapping Radio component values as
{"value": "replace", "__type__": "update"} instead of plain strings,
causing the update_settings Gradio call to fail and crash the server.

- /update-settings: removed Gradio call, settings are applied at save time
- /save-dataset: migrated to REST API (/v1/dataset/save) which accepts
  tag_position and other settings directly as strings
- Frontend: pass dataset settings (tag, position, etc.) when saving
This commit is contained in:
fspecii
2026-03-02 18:06:44 +02:00
parent a5879e60a5
commit 78426c00dd
3 changed files with 39 additions and 27 deletions
+4
View File
@@ -474,6 +474,10 @@ export const TrainingPanel: React.FC = () => {
const result = await trainingApi.saveDataset({
savePath: savePath || `./datasets/${datasetSettings.datasetName}.json`,
datasetName: datasetSettings.datasetName,
customTag: datasetSettings.customTag,
tagPosition: datasetSettings.tagPosition,
allInstrumental: datasetSettings.allInstrumental,
genreRatio: datasetSettings.genreRatio,
}, token);
setSaveStatus(result.status as string);
if (result.path) setSavePath(result.path);
+30 -26
View File
@@ -717,41 +717,45 @@ router.post('/save-sample', authMiddleware, async (req: AuthenticatedRequest, re
});
// POST /api/training/update-settings — Update dataset global settings
router.post('/update-settings', authMiddleware, async (req: AuthenticatedRequest, res: Response) => {
try {
const { customTag, tagPosition, allInstrumental, genreRatio } = req.body;
const client = await getGradioClient();
await client.predict('/update_settings', [
customTag ?? '',
tagPosition ?? 'replace',
allInstrumental ?? true,
genreRatio ?? 0,
]);
// Settings are applied directly when saving (via REST API), so no Gradio call needed here.
router.post('/update-settings', authMiddleware, (_req: AuthenticatedRequest, res: Response) => {
res.json({ success: true });
} catch (error) {
console.error('[Training] Update settings error:', error);
res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to update settings' });
}
});
// POST /api/training/save-dataset — Save the dataset to a JSON file
router.post('/save-dataset', authMiddleware, async (req: AuthenticatedRequest, res: Response) => {
try {
const { savePath, datasetName } = req.body;
const { savePath, datasetName, customTag, tagPosition, allInstrumental, genreRatio } = req.body;
const client = await getGradioClient();
const result = await client.predict('/save_dataset', [
savePath ?? './datasets/my_lora_dataset.json',
datasetName ?? 'my_lora_dataset',
]);
const data = result.data as unknown[];
const resolvedPath = (savePath ?? `./datasets/${datasetName ?? 'my_lora_dataset'}.json`).trim();
// Returns: [saveStatus, savePath]
// Use REST API to avoid @gradio/client Radio serialization issues
const apiUrl = config.acestep.apiUrl;
const body: Record<string, unknown> = {
save_path: resolvedPath,
dataset_name: datasetName ?? 'my_lora_dataset',
};
if (customTag !== undefined) body.custom_tag = customTag;
if (tagPosition !== undefined) body.tag_position = tagPosition;
if (allInstrumental !== undefined) body.all_instrumental = allInstrumental;
if (genreRatio !== undefined) body.genre_ratio = genreRatio;
const apiRes = await fetch(`${apiUrl}/v1/dataset/save`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
signal: AbortSignal.timeout(30_000),
});
if (!apiRes.ok) {
const err = await apiRes.json().catch(() => ({})) as any;
throw new Error(err?.detail || err?.error || `Save failed: ${apiRes.status}`);
}
const data = await apiRes.json() as any;
res.json({
status: data[0],
path: data[1],
status: data.status ?? 'Saved',
path: data.save_path ?? resolvedPath,
});
} catch (error) {
console.error('[Training] Save dataset error:', error);
+4
View File
@@ -768,6 +768,10 @@ export const trainingApi = {
saveDataset: (params: {
savePath?: string;
datasetName?: string;
customTag?: string;
tagPosition?: string;
allInstrumental?: boolean;
genreRatio?: number;
}, token: string): Promise<{ status: string; path: string }> =>
api('/api/training/save-dataset', { method: 'POST', body: params, token }),