add process step
parent
b336bc6008
commit
826a1fbe1e
|
|
@ -68,7 +68,11 @@ function calculateProgress(process) {
|
||||||
remaining: process.progress.remaining_time || '计算中...',
|
remaining: process.progress.remaining_time || '计算中...',
|
||||||
loss: process.progress.current_loss || null,
|
loss: process.progress.current_loss || null,
|
||||||
epoch: process.progress.current_epoch ? `${process.progress.current_epoch}/${process.progress.total_epochs}` : null,
|
epoch: process.progress.current_epoch ? `${process.progress.current_epoch}/${process.progress.total_epochs}` : null,
|
||||||
lr: process.progress.current_lr || null
|
lr: process.progress.current_lr || null,
|
||||||
|
step: process.progress.current_step && process.progress.total_steps ?
|
||||||
|
`${process.progress.current_step}/${process.progress.total_steps}` : null,
|
||||||
|
currentStep: process.progress.current_step || 0,
|
||||||
|
totalSteps: process.progress.total_steps || 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,6 +92,9 @@ function calculateProgress(process) {
|
||||||
let current = 0;
|
let current = 0;
|
||||||
let total = 0;
|
let total = 0;
|
||||||
let percentage = 0;
|
let percentage = 0;
|
||||||
|
let currentStep = 0;
|
||||||
|
let totalSteps = 0;
|
||||||
|
let stepInfo = null;
|
||||||
|
|
||||||
for (const pattern of epochPatterns) {
|
for (const pattern of epochPatterns) {
|
||||||
const match = logText.match(pattern);
|
const match = logText.match(pattern);
|
||||||
|
|
@ -99,6 +106,28 @@ function calculateProgress(process) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提取step信息 - 支持多种格式
|
||||||
|
const stepPatterns = [
|
||||||
|
/step\s+(\d+)\s*\/\s*(\d+)/i, // step 150/1000
|
||||||
|
/Step\s+(\d+)\s*of\s*(\d+)/i, // Step 150 of 1000
|
||||||
|
/\[(\d+)\/(\d+)\]/i, // [150/1000]
|
||||||
|
/step\s*[::]\s*(\d+)\s*\/\s*(\d+)/i, // step: 150/1000
|
||||||
|
/第\s*(\d+)\s*步\s*\/\s*共\s*(\d+)\s*步/i, // 第150步/共1000步
|
||||||
|
/步数\s*(\d+)\s*\/\s*(\d+)/i, // 步数 150/1000
|
||||||
|
/batch\s+(\d+)\s*\/\s*(\d+)/i, // batch 150/1000
|
||||||
|
/Batch\s+(\d+)\s*of\s*(\d+)/i // Batch 150 of 1000
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const pattern of stepPatterns) {
|
||||||
|
const match = logText.match(pattern);
|
||||||
|
if (match) {
|
||||||
|
currentStep = parseInt(match[1]);
|
||||||
|
totalSteps = parseInt(match[2]);
|
||||||
|
stepInfo = `${currentStep}/${totalSteps}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 提取loss信息 - 支持多种格式
|
// 提取loss信息 - 支持多种格式
|
||||||
const lossPatterns = [
|
const lossPatterns = [
|
||||||
/loss[\s:=]\s*([\d.]+(?:e[+-]?\d+)?)/i, // loss: 4.32 or loss = 4.32
|
/loss[\s:=]\s*([\d.]+(?:e[+-]?\d+)?)/i, // loss: 4.32 or loss = 4.32
|
||||||
|
|
@ -149,14 +178,29 @@ function calculateProgress(process) {
|
||||||
|
|
||||||
// 如果找到了有效的epoch信息,返回进度
|
// 如果找到了有效的epoch信息,返回进度
|
||||||
if (total > 0) {
|
if (total > 0) {
|
||||||
|
// 重新计算百分比 - 支持epoch和step双重进度
|
||||||
|
let finalPercentage = percentage;
|
||||||
|
if (totalSteps > 0 && currentStep > 0) {
|
||||||
|
// 基础epoch进度
|
||||||
|
const epochPercentage = (current / total) * 100;
|
||||||
|
// 当前epoch内的step进度
|
||||||
|
const stepPercentageInEpoch = (currentStep / totalSteps) * 100;
|
||||||
|
// 将step进度加到epoch进度上(每个epoch占总进度的1/total)
|
||||||
|
const stepContribution = stepPercentageInEpoch / total;
|
||||||
|
finalPercentage = Math.min(100, Math.max(0, Math.round(epochPercentage + stepContribution)));
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
percentage,
|
percentage: finalPercentage,
|
||||||
current,
|
current,
|
||||||
total,
|
total,
|
||||||
remaining: calculateRemainingTime(current, total, logText),
|
remaining: calculateRemainingTime(current, total, logText),
|
||||||
loss: currentLoss,
|
loss: currentLoss,
|
||||||
epoch: `${current}/${total}`,
|
epoch: `${current}/${total}`,
|
||||||
lr: currentLr
|
lr: currentLr,
|
||||||
|
step: stepInfo,
|
||||||
|
currentStep,
|
||||||
|
totalSteps
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -321,12 +365,13 @@ export function addProcessItemToGroup(parent, process) {
|
||||||
<div class="progress-fill" style="width: ${progressInfo.percentage}%"></div>
|
<div class="progress-fill" style="width: ${progressInfo.percentage}%"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="progress-info">
|
<div class="progress-info">
|
||||||
<span>进度: ${progressInfo.current}/${progressInfo.total}</span>
|
<span>进度: ${progressInfo.current}/${progressInfo.total}${progressInfo.step ? ` (${progressInfo.step})` : ''}</span>
|
||||||
<span>剩余时间: ${progressInfo.remaining}</span>
|
<span>剩余时间: ${progressInfo.remaining}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="progress-metrics">
|
<div class="progress-metrics">
|
||||||
${progressInfo.loss ? `<div class="metric-item"><span class="metric-label">Loss:</span><span class="metric-value">${progressInfo.loss}</span></div>` : ''}
|
${progressInfo.loss ? `<div class="metric-item"><span class="metric-label">Loss:</span><span class="metric-value">${progressInfo.loss}</span></div>` : ''}
|
||||||
${progressInfo.epoch ? `<div class="metric-item"><span class="metric-label">Epoch:</span><span class="metric-value">${progressInfo.epoch}</span></div>` : ''}
|
${progressInfo.epoch ? `<div class="metric-item"><span class="metric-label">Epoch:</span><span class="metric-value">${progressInfo.epoch}</span></div>` : ''}
|
||||||
|
${progressInfo.step ? `<div class="metric-item"><span class="metric-label">Step:</span><span class="metric-value">${progressInfo.step}</span></div>` : ''}
|
||||||
${progressInfo.lr ? `<div class="metric-item"><span class="metric-label">LR:</span><span class="metric-value">${progressInfo.lr}</span></div>` : ''}
|
${progressInfo.lr ? `<div class="metric-item"><span class="metric-label">LR:</span><span class="metric-value">${progressInfo.lr}</span></div>` : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -379,7 +424,8 @@ export function updateProcessProgress(item, process) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progressText) {
|
if (progressText) {
|
||||||
progressText.textContent = `进度: ${progressInfo.current}/${progressInfo.total}`;
|
const stepText = progressInfo.step ? ` (${progressInfo.step})` : '';
|
||||||
|
progressText.textContent = `进度: ${progressInfo.current}/${progressInfo.total}${stepText}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remainingText) {
|
if (remainingText) {
|
||||||
|
|
@ -390,7 +436,8 @@ export function updateProcessProgress(item, process) {
|
||||||
// 更新指标 - 只更新有变化的值来减少DOM操作
|
// 更新指标 - 只更新有变化的值来减少DOM操作
|
||||||
const lossItem = metricsContainer.querySelector('.metric-item:nth-child(1) .metric-value');
|
const lossItem = metricsContainer.querySelector('.metric-item:nth-child(1) .metric-value');
|
||||||
const epochItem = metricsContainer.querySelector('.metric-item:nth-child(2) .metric-value');
|
const epochItem = metricsContainer.querySelector('.metric-item:nth-child(2) .metric-value');
|
||||||
const lrItem = metricsContainer.querySelector('.metric-item:nth-child(3) .metric-value');
|
const stepItem = metricsContainer.querySelector('.metric-item:nth-child(3) .metric-value');
|
||||||
|
const lrItem = metricsContainer.querySelector('.metric-item:nth-child(4) .metric-value');
|
||||||
|
|
||||||
if (progressInfo.loss && lossItem) {
|
if (progressInfo.loss && lossItem) {
|
||||||
lossItem.textContent = progressInfo.loss;
|
lossItem.textContent = progressInfo.loss;
|
||||||
|
|
@ -398,6 +445,9 @@ export function updateProcessProgress(item, process) {
|
||||||
if (progressInfo.epoch && epochItem) {
|
if (progressInfo.epoch && epochItem) {
|
||||||
epochItem.textContent = progressInfo.epoch;
|
epochItem.textContent = progressInfo.epoch;
|
||||||
}
|
}
|
||||||
|
if (progressInfo.step && stepItem) {
|
||||||
|
stepItem.textContent = progressInfo.step;
|
||||||
|
}
|
||||||
if (progressInfo.lr && lrItem) {
|
if (progressInfo.lr && lrItem) {
|
||||||
lrItem.textContent = progressInfo.lr;
|
lrItem.textContent = progressInfo.lr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ def calculate_training_progress(process_id, process_info):
|
||||||
'percentage': 0,
|
'percentage': 0,
|
||||||
'current_epoch': 0,
|
'current_epoch': 0,
|
||||||
'total_epochs': 0,
|
'total_epochs': 0,
|
||||||
|
'current_step': 0,
|
||||||
|
'total_steps': 0,
|
||||||
'remaining_time': '计算中...',
|
'remaining_time': '计算中...',
|
||||||
'current_loss': None,
|
'current_loss': None,
|
||||||
'current_lr': None
|
'current_lr': None
|
||||||
|
|
@ -110,6 +112,26 @@ def calculate_training_progress(process_id, process_info):
|
||||||
total_epochs = int(match.group(2))
|
total_epochs = int(match.group(2))
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# 提取step信息 - 支持多种格式
|
||||||
|
# 格式: step 150/1000, Step 150 of 1000, [150/1000], step: 150/1000
|
||||||
|
step_patterns = [
|
||||||
|
r'step\s+(\d+)\s*/\s*(\d+)',
|
||||||
|
r'Step\s+(\d+)\s*of\s*(\d+)',
|
||||||
|
r'\[(\d+)/(\d+)\]',
|
||||||
|
r'step\s*[::]\s*(\d+)\s*/\s*(\d+)',
|
||||||
|
r'第\s*(\d+)\s*步\s*/\s*共\s*(\d+)\s*步',
|
||||||
|
r'步数\s*(\d+)\s*/\s*(\d+)',
|
||||||
|
r'batch\s+(\d+)\s*/\s*(\d+)', # 也支持batch格式
|
||||||
|
r'Batch\s+(\d+)\s*of\s*(\d+)'
|
||||||
|
]
|
||||||
|
|
||||||
|
for pattern in step_patterns:
|
||||||
|
match = re.search(pattern, line, re.IGNORECASE)
|
||||||
|
if match:
|
||||||
|
progress['current_step'] = int(match.group(1))
|
||||||
|
progress['total_steps'] = int(match.group(2))
|
||||||
|
break
|
||||||
|
|
||||||
# 提取loss信息 - 支持多种格式
|
# 提取loss信息 - 支持多种格式
|
||||||
if not current_loss:
|
if not current_loss:
|
||||||
# 格式: loss: 4.32, training_loss: 4.32, train_loss: 4.32, Loss: 4.32, 训练损失: 4.32
|
# 格式: loss: 4.32, training_loss: 4.32, train_loss: 4.32, Loss: 4.32, 训练损失: 4.32
|
||||||
|
|
@ -157,10 +179,29 @@ def calculate_training_progress(process_id, process_info):
|
||||||
if total_epochs and current_loss and current_lr:
|
if total_epochs and current_loss and current_lr:
|
||||||
break
|
break
|
||||||
|
|
||||||
# 计算进度百分比
|
# 计算进度百分比 - 支持epoch和step双重进度
|
||||||
percentage = 0
|
percentage = 0
|
||||||
if total_epochs > 0:
|
if total_epochs > 0:
|
||||||
percentage = min(100, max(0, int((current_epoch / total_epochs) * 100)))
|
# 基础epoch进度
|
||||||
|
epoch_percentage = (current_epoch / total_epochs) * 100
|
||||||
|
|
||||||
|
# 如果有step信息,在当前epoch内计算step进度
|
||||||
|
if progress['total_steps'] > 0 and progress['current_step'] > 0:
|
||||||
|
# 计算当前epoch内的step进度
|
||||||
|
step_percentage_in_epoch = (progress['current_step'] / progress['total_steps']) * 100
|
||||||
|
# 将step进度加到epoch进度上(每个epoch占总进度的1/total_epochs)
|
||||||
|
step_contribution = step_percentage_in_epoch / total_epochs
|
||||||
|
percentage = min(100, max(0, int(epoch_percentage + step_contribution)))
|
||||||
|
else:
|
||||||
|
# 只有epoch信息的传统计算方式
|
||||||
|
percentage = min(100, max(0, int(epoch_percentage)))
|
||||||
|
|
||||||
|
# 更新进度字典
|
||||||
|
progress['percentage'] = percentage
|
||||||
|
progress['current_epoch'] = current_epoch
|
||||||
|
progress['total_epochs'] = total_epochs
|
||||||
|
progress['current_loss'] = current_loss
|
||||||
|
progress['current_lr'] = current_lr
|
||||||
|
|
||||||
# 估算剩余时间(增强计算)
|
# 估算剩余时间(增强计算)
|
||||||
remaining_time = '计算中...'
|
remaining_time = '计算中...'
|
||||||
|
|
@ -398,7 +439,7 @@ def add_test_process():
|
||||||
|
|
||||||
process_id = f"test_process_{int(time.time())}"
|
process_id = f"test_process_{int(time.time())}"
|
||||||
|
|
||||||
# 创建测试训练命令
|
# 创建测试训练命令 - 包含step进度
|
||||||
test_command = [
|
test_command = [
|
||||||
'python', '-c', '''
|
'python', '-c', '''
|
||||||
import time
|
import time
|
||||||
|
|
@ -416,23 +457,28 @@ print("2024-11-21 14:30:02 - Model initialized with 108M parameters")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
for epoch in range(1, 6):
|
# 测试单epoch但多step的情况
|
||||||
print(f"2024-11-21 14:30:{5 + epoch*5} - Starting epoch {epoch}/5")
|
print("2024-11-21 14:30:03 - Starting epoch 1/1")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
loss = 4.5 - epoch * 0.3
|
total_steps = 20
|
||||||
lr = 1e-4 * (0.9 ** epoch)
|
for step in range(1, total_steps + 1):
|
||||||
print(f"2024-11-21 14:30:{6 + epoch*5} - Loss: {loss:.4f}, lr: {lr:.2e}")
|
# 模拟step进度
|
||||||
sys.stdout.flush()
|
if step % 5 == 0 or step == total_steps:
|
||||||
time.sleep(2)
|
print(f"2024-11-21 14:30:{4 + step} - Step {step}/{total_steps}")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
remaining = (5 - epoch) * 15
|
# 模拟训练过程
|
||||||
print(f"2024-11-21 14:30:{8 + epoch*5} - Epoch {epoch}/5 completed, remaining: 0:0{remaining}:00")
|
loss = 4.5 - step * 0.1
|
||||||
sys.stdout.flush()
|
lr = 1e-4 * (0.95 ** step)
|
||||||
time.sleep(1)
|
if step % 3 == 0:
|
||||||
|
print(f"2024-11-21 14:30:{4 + step} - Loss: {loss:.4f}, lr: {lr:.2e}")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
print("2024-11-21 14:30:35 - Training completed successfully")
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
print("2024-11-21 14:30:25 - Training completed successfully")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
'''
|
'''
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{}
|
||||||
Loading…
Reference in New Issue