Upload 3 files
Browse files- claude_analysis.py +164 -0
- finetune_analysis.sh +130 -0
- finetune_pipeline.sh +107 -0
claude_analysis.py
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
# -*- coding: utf-8 -*-
|
| 3 |
+
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
import json
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
|
| 9 |
+
try:
|
| 10 |
+
import anthropic
|
| 11 |
+
except ImportError:
|
| 12 |
+
print("\nERROR: anthropic library is not installed")
|
| 13 |
+
print("To install, run: pip install anthropic")
|
| 14 |
+
print("or: python -m pip install anthropic\n")
|
| 15 |
+
print(json.dumps({"error": "Missing anthropic library. Please run: pip install anthropic"}))
|
| 16 |
+
sys.exit(1)
|
| 17 |
+
|
| 18 |
+
# Проверяем версию anthropic
|
| 19 |
+
try:
|
| 20 |
+
anthropic_version = anthropic.__version__
|
| 21 |
+
print(f"\nDEBUG - Using anthropic version: {anthropic_version}")
|
| 22 |
+
except:
|
| 23 |
+
print("\nWARNING - Could not determine anthropic version")
|
| 24 |
+
|
| 25 |
+
api_key = os.environ.get("ANTHROPIC_API_KEY", "")
|
| 26 |
+
# api_key = "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"
|
| 27 |
+
if not api_key:
|
| 28 |
+
print(json.dumps({"error": "No ANTHROPIC_API_KEY provided"}))
|
| 29 |
+
sys.exit(0)
|
| 30 |
+
|
| 31 |
+
def get_txt_contents(local_path=None):
|
| 32 |
+
"""
|
| 33 |
+
Получает содержимое .txt файлов либо из локальной папки, либо из аргументов командной строки
|
| 34 |
+
"""
|
| 35 |
+
txt_contents = []
|
| 36 |
+
|
| 37 |
+
# Пробуем использовать локальную папку
|
| 38 |
+
if local_path:
|
| 39 |
+
try:
|
| 40 |
+
path = Path(local_path)
|
| 41 |
+
if path.exists():
|
| 42 |
+
print(f"\nDEBUG - Reading files from local path: {path}")
|
| 43 |
+
for txt_file in path.glob("*.txt"):
|
| 44 |
+
try:
|
| 45 |
+
with open(txt_file, 'r', encoding='utf-8') as f:
|
| 46 |
+
txt_contents.append(f.read())
|
| 47 |
+
print(f"DEBUG - Read file: {txt_file.name}")
|
| 48 |
+
except Exception as e:
|
| 49 |
+
print(f"DEBUG - Error reading {txt_file}: {e}")
|
| 50 |
+
return txt_contents
|
| 51 |
+
except Exception as e:
|
| 52 |
+
print(f"\nDEBUG - Error accessing local path: {e}")
|
| 53 |
+
|
| 54 |
+
# Если локальная папка недоступна, используем аргументы командной строки
|
| 55 |
+
txt_file_list = sys.argv[1:]
|
| 56 |
+
if not txt_file_list:
|
| 57 |
+
return txt_contents
|
| 58 |
+
|
| 59 |
+
for f in txt_file_list:
|
| 60 |
+
try:
|
| 61 |
+
with open(f, 'r', encoding='utf-8') as ff:
|
| 62 |
+
txt_contents.append(ff.read())
|
| 63 |
+
except Exception as e:
|
| 64 |
+
print(f"DEBUG - Error reading {f}: {e}")
|
| 65 |
+
|
| 66 |
+
return txt_contents
|
| 67 |
+
|
| 68 |
+
# -----------------------------------------------------------------------------
|
| 69 |
+
# 1. Собираем список файлов
|
| 70 |
+
# -----------------------------------------------------------------------------
|
| 71 |
+
local_path = r"G:\My Drive\Kohya_SS\Flux\SoloBand\IconsGray"
|
| 72 |
+
txt_contents = get_txt_contents(local_path)
|
| 73 |
+
|
| 74 |
+
if not txt_contents:
|
| 75 |
+
print("\nDEBUG - No text files found in local path or arguments")
|
| 76 |
+
|
| 77 |
+
combined_text = "\n---\n".join(txt_contents)
|
| 78 |
+
|
| 79 |
+
# -----------------------------------------------------------------------------
|
| 80 |
+
# 2. Формируем промпт для Claude
|
| 81 |
+
# -----------------------------------------------------------------------------
|
| 82 |
+
prompt_content = f"""You are a highly creative AI art director. Your task is to generate an imaginative and specific JSON response. Never use "Unknown" values - instead, create interesting and unique artistic directions even without input files.
|
| 83 |
+
|
| 84 |
+
You MUST ALWAYS return ONLY a valid JSON object in this exact format, with no additional text:
|
| 85 |
+
|
| 86 |
+
{{
|
| 87 |
+
"token": "Choose exactly one: FD_AI (Fantasy & Dragons), SB_AI (Storybook), CM_AI (Comic), AN_AI (Anime), RT_AI (Realistic)",
|
| 88 |
+
"art_type": "Create a specific description like: 'Mystical Forest Portal', 'Neon Cyberpunk City', 'Cozy Cottage Interior', 'Ancient Dragon Lair', 'Futuristic Space Station'",
|
| 89 |
+
"style_name": "Define clear style like: 'Vibrant watercolor fantasy', 'Detailed pencil illustration', 'Dark gothic oil painting', 'Cute kawaii digital art', 'Cinematic 3D render'",
|
| 90 |
+
"model_name": "Will be auto-generated as {{token}}_{{art_type}}_V1",
|
| 91 |
+
"prompts": [
|
| 92 |
+
"Generate 6 detailed prompts that perfectly match the art_type and style_name",
|
| 93 |
+
"Each prompt should be unique and vivid",
|
| 94 |
+
"Include specific details about composition, lighting, mood, colors",
|
| 95 |
+
"Keep each prompt to 1-2 impactful sentences",
|
| 96 |
+
"Focus on visual elements rather than story",
|
| 97 |
+
"Maintain consistent style across all prompts"
|
| 98 |
+
]
|
| 99 |
+
}}
|
| 100 |
+
|
| 101 |
+
Even with no input files, you must generate a creative and complete response using the available tokens and styles. Never return "Unknown" values.
|
| 102 |
+
|
| 103 |
+
Input content to analyze (if any):
|
| 104 |
+
---
|
| 105 |
+
{combined_text}
|
| 106 |
+
"""
|
| 107 |
+
|
| 108 |
+
# Добавляем отладочный вывод промпта
|
| 109 |
+
print("\nDEBUG - Full prompt being sent to Claude:")
|
| 110 |
+
print("="*80)
|
| 111 |
+
print(prompt_content)
|
| 112 |
+
print("="*80)
|
| 113 |
+
|
| 114 |
+
# -----------------------------------------------------------------------------
|
| 115 |
+
# 3. Обращаемся к Anthropic (Claude) с указанной моделью
|
| 116 |
+
# -----------------------------------------------------------------------------
|
| 117 |
+
try:
|
| 118 |
+
client = anthropic.Anthropic(api_key=api_key)
|
| 119 |
+
message = client.messages.create(
|
| 120 |
+
model="claude-3-sonnet-20240229",
|
| 121 |
+
max_tokens=1024,
|
| 122 |
+
messages=[
|
| 123 |
+
{
|
| 124 |
+
"role": "user",
|
| 125 |
+
"content": prompt_content
|
| 126 |
+
}
|
| 127 |
+
],
|
| 128 |
+
temperature=0.7,
|
| 129 |
+
)
|
| 130 |
+
raw_reply = message.content[0].text
|
| 131 |
+
except Exception as e:
|
| 132 |
+
print(json.dumps({"error": f"Request to Claude failed: {str(e)}"}))
|
| 133 |
+
sys.exit(0)
|
| 134 |
+
|
| 135 |
+
# -----------------------------------------------------------------------------
|
| 136 |
+
# 4. Пытаемся интерпретировать ответ как JSON
|
| 137 |
+
# -----------------------------------------------------------------------------
|
| 138 |
+
try:
|
| 139 |
+
data = json.loads(raw_reply)
|
| 140 |
+
except:
|
| 141 |
+
# Если парсить напрямую не получается, отправим ошибку
|
| 142 |
+
print(json.dumps({"error": "Claude response is not valid JSON", "raw_reply": raw_reply}))
|
| 143 |
+
sys.exit(0)
|
| 144 |
+
|
| 145 |
+
# -----------------------------------------------------------------------------
|
| 146 |
+
# 5. (опционально) Проверяем, что в ответе есть нужные поля
|
| 147 |
+
# -----------------------------------------------------------------------------
|
| 148 |
+
token = data.get("token", "SB_AI")
|
| 149 |
+
art_type = data.get("art_type", "UnknownArtType")
|
| 150 |
+
style_name = data.get("style_name", "UnknownStyle")
|
| 151 |
+
model_name = data.get("model_name", f"{token}_{art_type}_V1")
|
| 152 |
+
prompts = data.get("prompts", [])
|
| 153 |
+
|
| 154 |
+
# -----------------------------------------------------------------------------
|
| 155 |
+
# 6. Выводим финальный JSON в stdout
|
| 156 |
+
# -----------------------------------------------------------------------------
|
| 157 |
+
out = {
|
| 158 |
+
"token": token,
|
| 159 |
+
"art_type": art_type,
|
| 160 |
+
"style_name": style_name,
|
| 161 |
+
"model_name": model_name,
|
| 162 |
+
"prompts": prompts
|
| 163 |
+
}
|
| 164 |
+
print(json.dumps(out, ensure_ascii=False))
|
finetune_analysis.sh
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -e
|
| 3 |
+
|
| 4 |
+
echo ">>> [Script 2] This script will handle Claude analysis and config update."
|
| 5 |
+
|
| 6 |
+
###############################################################################
|
| 7 |
+
# 1. Ожидание нажатия Enter и получение дополнительных комментариев
|
| 8 |
+
###############################################################################
|
| 9 |
+
echo ">>> [Script 2] Нажмите Enter, чтобы продолжить распаковку и анализ .txt файлов ..."
|
| 10 |
+
read
|
| 11 |
+
|
| 12 |
+
echo ">>> [Script 2] Введите дополнительные комментарии по поводу арта (или нажмите Enter, чтобы пропустить):"
|
| 13 |
+
read USER_COMMENTS
|
| 14 |
+
|
| 15 |
+
###############################################################################
|
| 16 |
+
# 2. Распаковываем все .zip в /workspace/MyLearningDataset/Images
|
| 17 |
+
###############################################################################
|
| 18 |
+
echo ">>> [Script 2] Unzipping all .zip in /workspace/MyLearningDataset/Images ..."
|
| 19 |
+
find /workspace/MyLearningDataset/Images -type f -name '*.zip' | while read zipf; do
|
| 20 |
+
unzip -o "$zipf" -d /workspace/MyLearningDataset/Images
|
| 21 |
+
rm -f "$zipf"
|
| 22 |
+
done
|
| 23 |
+
|
| 24 |
+
###############################################################################
|
| 25 |
+
# 3. Собираем до 35 .txt файлов
|
| 26 |
+
###############################################################################
|
| 27 |
+
echo ">>> [Script 2] Collecting up to 35 .txt files ..."
|
| 28 |
+
TXT_FILES=$(find /workspace/MyLearningDataset/Images -type f -name '*.txt' | head -n 35)
|
| 29 |
+
|
| 30 |
+
if [ -z "$TXT_FILES" ]; then
|
| 31 |
+
echo "[Script 2] WARNING: No .txt files found (up to 35)."
|
| 32 |
+
fi
|
| 33 |
+
|
| 34 |
+
###############################################################################
|
| 35 |
+
# 4. Устанавливаем библиотеку anthropic (если не установлена)
|
| 36 |
+
# И указываем ANTHROPIC_API_KEY
|
| 37 |
+
###############################################################################
|
| 38 |
+
echo ">>> [Script 2] Installing anthropic library (if needed) ..."
|
| 39 |
+
pip install anthropic
|
| 40 |
+
|
| 41 |
+
# Подставьте ваш реальный ключ, если нужно
|
| 42 |
+
ANTHROPIC_API_KEY="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"
|
| 43 |
+
export ANTHROPIC_API_KEY
|
| 44 |
+
|
| 45 |
+
###############################################################################
|
| 46 |
+
# 5. Запускаем Python-скрипт claude_analysis.py, передавая список файлов
|
| 47 |
+
###############################################################################
|
| 48 |
+
echo ">>> [Script 2] Sending request to Claude via claude_analysis.py ..."
|
| 49 |
+
PARSED_JSON=$(python /workspace/claude_analysis.py "$TXT_FILES" "$USER_COMMENTS" 2>/dev/null || true)
|
| 50 |
+
|
| 51 |
+
if [ -z "$PARSED_JSON" ]; then
|
| 52 |
+
echo "[Script 2] ERROR: Claude response is empty or not found."
|
| 53 |
+
exit 1
|
| 54 |
+
fi
|
| 55 |
+
|
| 56 |
+
# Проверка на ошибку (на всякий случай)
|
| 57 |
+
if [[ "$PARSED_JSON" == *"error"* ]]; then
|
| 58 |
+
echo "[Script 2] ERROR: JSON parse problem. See logs."
|
| 59 |
+
echo "$PARSED_JSON"
|
| 60 |
+
exit 1
|
| 61 |
+
fi
|
| 62 |
+
|
| 63 |
+
###############################################################################
|
| 64 |
+
# 6. Из полученного JSON извлекаем нужные поля (token, art_type, style_name, model_name, prompts)
|
| 65 |
+
###############################################################################
|
| 66 |
+
# Можно извлекать с помощью Python, jq или других инструментов. Для универсальности:
|
| 67 |
+
TOKEN=$(echo "$PARSED_JSON" | python -c 'import sys, json; d=json.load(sys.stdin); print(d["token"])')
|
| 68 |
+
ART_TYPE=$(echo "$PARSED_JSON" | python -c 'import sys, json; d=json.load(sys.stdin); print(d["art_type"])')
|
| 69 |
+
STYLE_NAME=$(echo "$PARSED_JSON" | python -c 'import sys, json; d=json.load(sys.stdin); print(d["style_name"])')
|
| 70 |
+
MODEL_NAME=$(echo "$PARSED_JSON" | python -c 'import sys, json; d=json.load(sys.stdin); print(d["model_name"])')
|
| 71 |
+
|
| 72 |
+
# Многострочные промпты (каждый элемент массива -> перенос строки)
|
| 73 |
+
PROMPTS=$(echo "$PARSED_JSON" | python -c '
|
| 74 |
+
import sys, json
|
| 75 |
+
d=json.load(sys.stdin)
|
| 76 |
+
prompts = d.get("prompts", [])
|
| 77 |
+
print("\n".join(prompts))
|
| 78 |
+
')
|
| 79 |
+
|
| 80 |
+
echo ">>> [Script 2] Claude parsed result:"
|
| 81 |
+
echo "token = $TOKEN"
|
| 82 |
+
echo "art_type = $ART_TYPE"
|
| 83 |
+
echo "style_name = $STYLE_NAME"
|
| 84 |
+
echo "model_name = $MODEL_NAME"
|
| 85 |
+
echo "prompts:"
|
| 86 |
+
echo "$PROMPTS"
|
| 87 |
+
echo
|
| 88 |
+
|
| 89 |
+
###############################################################################
|
| 90 |
+
# 7. Переносим .txt и .png файлы в папку /workspace/MyLearningDataset/Images/1_{model_name}_{style_name}
|
| 91 |
+
###############################################################################
|
| 92 |
+
NEW_FOLDER="/workspace/MyLearningDataset/Images/1_${MODEL_NAME}_${STYLE_NAME}"
|
| 93 |
+
mkdir -p "$NEW_FOLDER"
|
| 94 |
+
|
| 95 |
+
echo ">>> [Script 2] Moving all .txt and .png files into $NEW_FOLDER ..."
|
| 96 |
+
find /workspace/MyLearningDataset/Images -type f \( -name '*.txt' -o -name '*.png' \) -exec mv -f {} "$NEW_FOLDER" \; 2>/dev/null || true
|
| 97 |
+
|
| 98 |
+
###############################################################################
|
| 99 |
+
# 8. Ищем FluxDatasetConfig.json и редактируем нужные поля
|
| 100 |
+
###############################################################################
|
| 101 |
+
FLUX_CONFIG_PATH=$(find /workspace -name "FluxDatasetConfig.json" | head -n 1)
|
| 102 |
+
if [ -z "$FLUX_CONFIG_PATH" ]; then
|
| 103 |
+
echo "[Script 2] ERROR: FluxDatasetConfig.json not found!"
|
| 104 |
+
exit 1
|
| 105 |
+
fi
|
| 106 |
+
|
| 107 |
+
echo ">>> [Script 2] Updating FluxDatasetConfig.json at $FLUX_CONFIG_PATH ..."
|
| 108 |
+
cat <<EOF > /workspace/update_flux_config.py
|
| 109 |
+
import json
|
| 110 |
+
|
| 111 |
+
path = r"${FLUX_CONFIG_PATH}"
|
| 112 |
+
with open(path, "r", encoding="utf-8") as f:
|
| 113 |
+
config = json.load(f)
|
| 114 |
+
|
| 115 |
+
config["train_data_dir"] = "/workspace/MyLearningDataset/Images"
|
| 116 |
+
config["output_dir"] = "/workspace/MyLearningDataset/Models"
|
| 117 |
+
config["output_name"] = "${MODEL_NAME}"
|
| 118 |
+
config["huggingface_repo_id"] = "Gerchegg/${MODEL_NAME}"
|
| 119 |
+
config["logging_dir"] = "/workspace/MyLearningDataset/Logs"
|
| 120 |
+
|
| 121 |
+
# Многострочные промпты
|
| 122 |
+
config["sample_prompts"] = """${PROMPTS}"""
|
| 123 |
+
|
| 124 |
+
with open(path, "w", encoding="utf-8") as f:
|
| 125 |
+
json.dump(config, f, ensure_ascii=False, indent=2)
|
| 126 |
+
EOF
|
| 127 |
+
|
| 128 |
+
python /workspace/update_flux_config.py
|
| 129 |
+
|
| 130 |
+
echo ">>> [Script 2] Done. Analysis complete!"
|
finetune_pipeline.sh
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -e
|
| 3 |
+
|
| 4 |
+
###############################################################################
|
| 5 |
+
# 0. Подготовка среды: обновление apt, установка unzip
|
| 6 |
+
###############################################################################
|
| 7 |
+
echo ">>> [Script 1] Step 0: Installing system dependencies ..."
|
| 8 |
+
apt-get update && apt-get install -y unzip
|
| 9 |
+
|
| 10 |
+
###############################################################################
|
| 11 |
+
# 1. Скачиваем zip-файл с Hugging Face и распаковываем
|
| 12 |
+
###############################################################################
|
| 13 |
+
echo ">>> [Script 1] Step 1: Downloading MyRunpodFinetuneScripts.zip ..."
|
| 14 |
+
wget -O /workspace/MyRunpodFinetuneScripts.zip \
|
| 15 |
+
"https://huggingface.co/Gerchegg/FeaturesFluxAI/resolve/main/MyRunpodFinetuneScripts.zip"
|
| 16 |
+
|
| 17 |
+
echo ">>> [Script 1] Step 2: Unzipping MyRunpodFinetuneScripts.zip ..."
|
| 18 |
+
unzip -o /workspace/MyRunpodFinetuneScripts.zip -d /workspace
|
| 19 |
+
# Предполагается, что внутри появится папка Kohya_Flux*** с нужными файлами.
|
| 20 |
+
|
| 21 |
+
###############################################################################
|
| 22 |
+
# 2. Запускаем два "параллельных" потока (фона):
|
| 23 |
+
# - Thread 1: Устанавливает пакеты + python Download_Train_Models.py
|
| 24 |
+
# - Thread 2: Устанавливает нужные deps (kohya_ss, torch, xformers), запускает GUI
|
| 25 |
+
###############################################################################
|
| 26 |
+
echo ">>> [Script 1] Starting parallel threads ..."
|
| 27 |
+
|
| 28 |
+
# ------------------ Поток 1 --------------------
|
| 29 |
+
(
|
| 30 |
+
echo ">>> [Thread 1] Installing Python packages for huggingface ..."
|
| 31 |
+
pip install huggingface_hub ipywidgets hf_transfer
|
| 32 |
+
|
| 33 |
+
export HF_HUB_ENABLE_HF_TRANSFER=1
|
| 34 |
+
|
| 35 |
+
echo ">>> [Thread 1] Running Download_Train_Models.py ..."
|
| 36 |
+
dwn_path=$(find /workspace -name "Download_Train_Models.py" | head -n 1)
|
| 37 |
+
if [ -z "$dwn_path" ]; then
|
| 38 |
+
echo "[Thread 1] ERROR: Download_Train_Models.py not found!"
|
| 39 |
+
exit 1
|
| 40 |
+
fi
|
| 41 |
+
|
| 42 |
+
python "$dwn_path" --dir /workspace
|
| 43 |
+
|
| 44 |
+
echo ">>> [Thread 1] Done."
|
| 45 |
+
) &
|
| 46 |
+
|
| 47 |
+
# ------------------ Поток 2 --------------------
|
| 48 |
+
(
|
| 49 |
+
echo ">>> [Thread 2] Installing Python and OS dependencies ..."
|
| 50 |
+
apt update --yes
|
| 51 |
+
yes | apt-get install python3.10-tk
|
| 52 |
+
apt-get install psmisc --yes
|
| 53 |
+
|
| 54 |
+
echo ">>> [Thread 2] Cloning kohya_ss ..."
|
| 55 |
+
cd /workspace
|
| 56 |
+
if [ ! -d "/workspace/kohya_ss" ]; then
|
| 57 |
+
git clone https://github.com/bmaltais/kohya_ss.git
|
| 58 |
+
fi
|
| 59 |
+
|
| 60 |
+
cd /workspace/kohya_ss
|
| 61 |
+
git checkout sd3-flux.1
|
| 62 |
+
|
| 63 |
+
echo ">>> [Thread 2] Creating Python venv ..."
|
| 64 |
+
python3 -m venv venv
|
| 65 |
+
source venv/bin/activate
|
| 66 |
+
yes | apt-get install python3.10-tk
|
| 67 |
+
|
| 68 |
+
echo ">>> [Thread 2] Running setup.sh ..."
|
| 69 |
+
./setup.sh -n -u
|
| 70 |
+
|
| 71 |
+
apt update --yes
|
| 72 |
+
yes | apt-get install python3.10-tk
|
| 73 |
+
apt-get install psmisc --yes
|
| 74 |
+
|
| 75 |
+
pip install hf_transfer
|
| 76 |
+
export HF_HUB_ENABLE_HF_TRANSFER=0
|
| 77 |
+
|
| 78 |
+
echo ">>> [Thread 2] Killing processes on port 7860 ..."
|
| 79 |
+
fuser -k 7860/tcp || true
|
| 80 |
+
|
| 81 |
+
git checkout sd3-flux.1
|
| 82 |
+
source venv/bin/activate
|
| 83 |
+
|
| 84 |
+
echo ">>> [Thread 2] Updating torch & xformers ..."
|
| 85 |
+
pip uninstall -y xformers
|
| 86 |
+
pip install torch==2.5.1+cu124 torchvision --index-url https://download.pytorch.org/whl/cu124
|
| 87 |
+
pip install xformers==0.0.28.post3 --index-url https://download.pytorch.org/whl/cu124
|
| 88 |
+
|
| 89 |
+
echo ">>> [Thread 2] Launching kohya_ss GUI on 0.0.0.0:7860 ..."
|
| 90 |
+
./gui.sh --listen=0.0.0.0 --share --noverify
|
| 91 |
+
) &
|
| 92 |
+
|
| 93 |
+
###############################################################################
|
| 94 |
+
# 3. Создаём общую структуру папок (Models, Images, Logs)
|
| 95 |
+
# по заданию, делаем это в первой части
|
| 96 |
+
###############################################################################
|
| 97 |
+
echo ">>> [Script 1] Creating folder structure in /workspace/MyLearningDataset ..."
|
| 98 |
+
mkdir -p /workspace/MyLearningDataset/Models
|
| 99 |
+
mkdir -p /workspace/MyLearningDataset/Images
|
| 100 |
+
mkdir -p /workspace/MyLearningDataset/Logs
|
| 101 |
+
|
| 102 |
+
###############################################################################
|
| 103 |
+
# 4. Ожидаем завершения потоков
|
| 104 |
+
###############################################################################
|
| 105 |
+
echo ">>> [Script 1] Waiting for threads to finish ..."
|
| 106 |
+
wait
|
| 107 |
+
echo ">>> [Script 1] ALL DONE! Now run 'finetune_analysis.sh' to proceed."
|