yanchang
yanchang
发布于 2025-10-12 / 17 阅读
1
0

AI生图+转换视频+换脸

内容脚本

#!/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


评论