内容脚本
#!/bin/bash
# run_manual_parallel_batch_with_progress.sh
# MODIFICATION: Record the start time for the entire script
GRAND_START_TIME=$(date +%s)
export HF_ENDPOINT=https://hf-mirror.com
export HF_HUB_OFFLINE=1
# ==============================================================================
# --- STAGE 1: PARALLEL IMAGE GENERATION ---
# ==============================================================================
echo "=============================================================================="
echo "🚀 STAGE 1: KICKING OFF PARALLEL IMAGE GENERATION"
echo "=============================================================================="
cd /home/yanchang/DATA/AIimage/OmniGen2/
# 切换到脚本所在目录
SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
cd $SHELL_FOLDER
# --- 配置参数 ---
MODEL_PATH="OmniGen2/OmniGen2"
OUTPUT_DIR="manual_batch_outputs"
PROMPTS_FILE="prompts.txt" # 提示词输入文件
TEMP_PROMPT_0="${OUTPUT_DIR}/temp_prompts_gpu0.txt"
TEMP_PROMPT_1="${OUTPUT_DIR}/temp_prompts_gpu1.txt"
DTYPE="fp16"
TIMESTAMP=$(date +%Y-%m-%d-%H-%M-%S)
# 确保输出目录存在
mkdir -p $OUTPUT_DIR
# 检查提示词文件是否存在
if [ ! -f "$PROMPTS_FILE" ]; then
echo "错误: 提示词文件 ${PROMPTS_FILE} 不存在!"
exit 1
fi
echo "--- Starting OmniGen2 Manual Parallel Batch Inference (With Progress) ---"
echo "Timestamp Prefix: ${TIMESTAMP}"
echo "--------------------------------------------------------"
# --- 1. 分割提示词文件 ---
TOTAL_LINES=$(grep -cve '^\s*$' "$PROMPTS_FILE")
if [ "$TOTAL_LINES" -eq 0 ]; then
echo "警告: 提示词文件 ${PROMPTS_FILE} 为空或不包含有效行。跳过图片生成。"
else
LINES_PER_GPU=$(( (TOTAL_LINES + 1) / 2 ))
echo "总提示词数量: $TOTAL_LINES"
echo "分配给每个 GPU 的数量 (约): $LINES_PER_GPU"
grep -ve '^\s*$' "$PROMPTS_FILE" | head -n $LINES_PER_GPU > "$TEMP_PROMPT_0"
grep -ve '^\s*$' "$PROMPTS_FILE" | tail -n +$((LINES_PER_GPU + 1)) > "$TEMP_PROMPT_1"
COUNT_GPU0=$(wc -l < "$TEMP_PROMPT_0")
COUNT_GPU1=$(wc -l < "$TEMP_PROMPT_1")
echo "实际分配 GPU 0: $COUNT_GPU0 个提示词"
echo "实际分配 GPU 1: $COUNT_GPU1 个提示词"
# --- 2. 定义运行子脚本函数 (添加进度和计时逻辑) ---
run_inference() {
local gpu_id=$1
local prompt_file=$2
local total_tasks=$3
local timestamp_prefix=$4
echo "------------------------------------------------"
echo "Starting Process on GPU $gpu_id. Total tasks: $total_tasks"
local index=0
while IFS= read -r instruction; do
local current_task=$((index + 1))
local percent=0
if [ "$total_tasks" -gt 0 ]; then
percent=$(echo "scale=0; ($current_task * 100) / $total_tasks" | bc)
fi
local output_name="${timestamp_prefix}-gpu${gpu_id}_$(printf "%03d" $index).png"
local output_path="${OUTPUT_DIR}/${output_name}"
echo -e "[GPU $gpu_id] Progress: ${percent}% (${current_task}/${total_tasks}) - Generating: $output_name"
local start_time_img=$(date +%s)
# MODIFICATION: Added '-u' to python for unbuffered output to show logs in real-time.
CUDA_VISIBLE_DEVICES=$gpu_id python -u inference.py \
--model_path $MODEL_PATH \
--num_inference_step 50 \
--height 1024 \
--width 1024 \
--text_guidance_scale 4 \
--instruction "$instruction" \
--output_image_path "$output_path" \
--num_images_per_prompt 1 \
--enable_model_cpu_offload \
--dtype $DTYPE
local end_time_img=$(date +%s)
local duration_img=$((end_time_img - start_time_img))
echo -e "[GPU $gpu_id] ✅ Finished '${output_name}' in ${duration_img} seconds."
index=$((index + 1))
done < "$prompt_file"
echo "Process on GPU $gpu_id finished. 100% complete."
}
# --- 3. 运行并行进程 ---
STAGE1_START_TIME=$(date +%s)
( run_inference 0 "$TEMP_PROMPT_0" "$COUNT_GPU0" "$TIMESTAMP" ) &
PID_GPU0=$!
( run_inference 1 "$TEMP_PROMPT_1" "$COUNT_GPU1" "$TIMESTAMP" ) &
PID_GPU1=$!
echo "Waiting for both parallel processes (PID $PID_GPU0 and PID $PID_GPU1) to complete..."
wait $PID_GPU0
wait $PID_GPU1
STAGE1_END_TIME=$(date +%s)
STAGE1_TOTAL_DURATION=$((STAGE1_END_TIME - STAGE1_START_TIME))
STAGE1_AVG_TIME=0
if [ "$TOTAL_LINES" -gt 0 ]; then
STAGE1_AVG_TIME=$((STAGE1_TOTAL_DURATION / TOTAL_LINES))
fi
# --- 4. 清理临时文件 ---
rm -f "$TEMP_PROMPT_0" "$TEMP_PROMPT_1"
echo "临时提示词文件已清理。"
echo "--------------------------------------------------------"
echo "📊 STAGE 1: IMAGE GENERATION SUMMARY"
echo "--------------------------------------------------------"
echo "Total images generated: ${TOTAL_LINES}"
echo "Total time taken for image generation: ${STAGE1_TOTAL_DURATION} seconds."
echo "Average time per image: ${STAGE1_AVG_TIME} seconds."
echo "--------------------------------------------------------"
fi
# ==============================================================================
# --- STAGE 2: BATCH VIDEO GENERATION ---
# ==============================================================================
echo ""
echo "=============================================================================="
echo "🎬 STAGE 2: KICKING OFF BATCH VIDEO GENERATION"
echo "=============================================================================="
export HF_HUB_OFFLINE=1
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
export CUDA_VISIBLE_DEVICES=0,1
cd /home/yanchang/DATA/AIvideo/LTX-Video
PROMPT="A girl"
NEGATIVE_PROMPT="(((deformed))), blurry, over saturation, bad anatomy, disfigured, poorly drawn face, mutation, mutated, (extra_limb), (ugly), (poorly drawn hands), fused fingers, messy drawing, broken legsm,(((Wearing clothes))),((No genitals shown))"
HEIGHT=512
WIDTH=512
NUM_FRAMES=65
FRAME_RATE=16
# SEED=42 # <--- 修改点 1: 删除固定的种子
PIPELINE_CONFIG="configs/ltxv-13b-0.9.8-distilled.yaml"
INPUT_DIR='/home/yanchang/DATA/AIimage/OmniGen2/manual_batch_outputs'
OUTPUT_DIR='/home/yanchang/DATA/AIvideo/LTX-Video/outputs'
if [ ! -d "$INPUT_DIR" ]; then
echo "错误: 输入目录 '$INPUT_DIR' 不存在。"
exit 1
fi
mkdir -p "$OUTPUT_DIR"
echo "视频输出将被保存到: $OUTPUT_DIR"
echo "开始批量处理图片生成视频..."
STAGE2_START_TIME=$(date +%s)
video_count=0
total_video_processing_time=0
while IFS= read -r image_path; do
if [ -f "$image_path" ]; then
video_count=$((video_count + 1))
# <--- 修改点 2: 在每次循环开始时生成一个新的随机种子
current_seed=$RANDOM
echo ""
echo "================================================================"
echo "🎬 正在处理图片 #$video_count: $(basename "$image_path")"
echo "================================================================"
image_filename_with_ext=$(basename "$image_path")
video_basename="${image_filename_with_ext%.*}"
output_video_path="${OUTPUT_DIR}/${video_basename}.mp4"
echo " ↳ 准备生成视频: ${output_video_path}"
# <--- 修改点 3 (推荐): 打印出当前使用的种子,方便复现
echo " 🌱 使用随机种子: ${current_seed}"
start_time_video=$(date +%s)
PYTHONUNBUFFERED=1 conda run -n ltxvideo_test python inference.py \
--prompt "$PROMPT" \
--negative_prompt "$NEGATIVE_PROMPT" \
--conditioning_media_paths "$image_path" \
--conditioning_start_frames 0 \
--height $HEIGHT \
--width $WIDTH \
--num_frames $NUM_FRAMES \
--frame_rate $FRAME_RATE \
--seed "$current_seed" \
--pipeline_config "$PIPELINE_CONFIG" \
--output_path "$output_video_path" \
--offload_to_cpu True
end_time_video=$(date +%s)
duration_video=$((end_time_video - start_time_video))
total_video_processing_time=$((total_video_processing_time + duration_video))
if [ $? -eq 0 ]; then
echo "✅ 成功生成视频. 耗时: ${duration_video} 秒."
else
echo "❌ 生成视频时发生错误. 耗时: ${duration_video} 秒."
fi
fi
done < <(find "$INPUT_DIR" -maxdepth 1 -type f \( -iname "*.png" -o -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.webp" \))
echo ""
echo "🎉 批量视频处理完成!"
STAGE2_END_TIME=$(date +%s)
STAGE2_TOTAL_DURATION=$((STAGE2_END_TIME - STAGE2_START_TIME))
STAGE2_AVG_TIME=0
if [ "$video_count" -gt 0 ]; then
STAGE2_AVG_TIME=$((total_video_processing_time / video_count))
fi
echo "--------------------------------------------------------"
echo "📊 STAGE 2: VIDEO GENERATION SUMMARY (CORRECTED)"
echo "--------------------------------------------------------"
echo "Total videos processed: ${video_count}"
echo "Total wall-clock time for video generation: ${STAGE2_TOTAL_DURATION} seconds."
echo "Sum of individual video processing times: ${total_video_processing_time} seconds."
echo "True average time per video: ${STAGE2_AVG_TIME} seconds."
echo "--------------------------------------------------------"
# ==============================================================================
# --- STAGE 3: FACEFUSION PROCESSING ---
# ==============================================================================
echo ""
echo "=============================================================================="
echo "🎭 STAGE 3: KICKING OFF FACEFUSION PROCESSING"
echo "=============================================================================="
cd /home/yanchang/DATA/facefusion
echo "切换到 $(pwd) 目录。"
echo "正在使用 'face' Conda 环境运行 start.py..."
STAGE3_START_TIME=$(date +%s)
# MODIFICATION: Added 'PYTHONUNBUFFERED=1' to show conda logs in real-time.
PYTHONUNBUFFERED=1 conda run -n face python start.py
STAGE3_END_TIME=$(date +%s)
STAGE3_TOTAL_DURATION=$((STAGE3_END_TIME - STAGE3_START_TIME))
echo "start.py 脚本已完成。"
echo "--------------------------------------------------------"
echo "📊 STAGE 3: FACEFUSION SUMMARY"
echo "--------------------------------------------------------"
echo "Total time for facefusion processing: ${STAGE3_TOTAL_DURATION} seconds."
echo "结果保存在: /home/yanchang/DATA/facefusion/data/output"
echo "--------------------------------------------------------"
# ==============================================================================
# --- FINAL SCRIPT SUMMARY ---
# ==============================================================================
GRAND_END_TIME=$(date +%s)
GRAND_TOTAL_DURATION=$((GRAND_END_TIME - GRAND_START_TIME))
echo ""
echo "=============================================================================="
echo "🏁 ENTIRE SCRIPT FINISHED 🏁"
echo "=============================================================================="
echo "Total execution time for all stages: ${GRAND_TOTAL_DURATION} seconds."
echo "=============================================================================="运行命令
nohup bash batch.sh > image.log 2>&1 &监控日志
tail -f image.log