HueGLoT / start.py
prostochel097's picture
обновил скрипт старта
79f959d verified
Raw
History Blame Contribute Delete
4.58 kB
import os
import torch
from torch import nn
import cv2
import numpy as np
from safetensors.torch import load_file, save_file
# архитектура
class VideoNet128(nn.Module):
def __init__(self):
super().__init__()
self.enc = nn.Sequential(
nn.Conv3d(3, 32, 3, padding=1), nn.ReLU(True), nn.MaxPool3d((1, 2, 2)),
nn.Conv3d(32, 64, 3, padding=1), nn.ReLU(True), nn.MaxPool3d((1, 2, 2)),
nn.Conv3d(64, 128, 3, padding=1), nn.ReLU(True), nn.MaxPool3d((1, 2, 2))
)
self.dec = nn.Sequential(
nn.Upsample(scale_factor=(1, 2, 2)), nn.Conv3d(128, 64, 3, padding=1), nn.ReLU(True),
nn.Upsample(scale_factor=(1, 2, 2)), nn.Conv3d(64, 32, 3, padding=1), nn.ReLU(True),
nn.Upsample(scale_factor=(1, 2, 2)), nn.Conv3d(32, 16, 3, padding=1), nn.ReLU(True),
nn.Conv3d(16, 3, 3, padding=1), nn.Tanh()
)
def forward(self, x):
return self.dec(self.enc(x))
# инициализация устройства
device = "cuda" if torch.cuda.is_available() else "cpu"
model = VideoNet128().to(device)
# конвертация и загрузка весов
pth_path = 'model.pth'
safetensors_path = 'model.safetensors'
if not os.path.exists(safetensors_path):
if os.path.exists(pth_path):
print("обнаружен старый формат весов! запускаю конвертацию в .safetensors...")
try:
model.load_state_dict(torch.load(pth_path, map_location='cpu'))
save_file(model.state_dict(), safetensors_path)
print("конвертация успешно завершена! создан файл model.safetensors.")
except Exception as e:
print(f"ошибка при конвертации: {e}")
else:
print(f"E: не найдены файлы весов ({pth_path} или {safetensors_path})!")
exit(1)
# загрузка через safetensors
try:
weights = load_file(safetensors_path, device=device)
model.load_state_dict(weights)
print("веса hueglot (.safetensors) успешно применены!")
except Exception as e:
print(f"критическая ошибка загрузки .safetensors: {e}!")
exit(1)
model.eval()
# обработка видео
def process_user_video(video_path, output_path="output.mp4"):
# читаем видео и нарезаем первые 16 кадров в разрешении 128x128
cap = cv2.VideoCapture(video_path)
frames = []
while len(frames) < 16:
ret, frame = cap.read()
if not ret:
break
frame = cv2.resize(frame, (128, 128))
frames.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
cap.release()
if len(frames) < 16:
print("E: видео слишком короткое, нужно минимум 16 кадров!")
return
# нормализация для hueglot (в диапазон от -1 до 1)
v = np.array(frames, dtype=np.float32)
v = torch.from_numpy(v).permute(3, 0, 1, 2).unsqueeze(0).to(device)
v = (v / 127.5) - 1.0
# прогоняем через нейросеть
print("перемалываем видео через латентное пространство...")
with torch.no_grad():
output = model(v)
vid = ((output.squeeze(0).clamp(-1, 1) + 1) / 2 * 255).cpu().numpy().astype(np.uint8).transpose(1, 2, 3, 0)
# программный апскейл до 1024x1024 в 60 fps
NEW_SIZE = (1024, 1024)
out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'), 60, NEW_SIZE)
print("рендерим плавные 60 FPS через интерполяцию кадров...")
for i in range(15):
frame1 = cv2.resize(cv2.cvtColor(vid[i], cv2.COLOR_RGB2BGR), NEW_SIZE, interpolation=cv2.INTER_CUBIC)
frame2 = cv2.resize(cv2.cvtColor(vid[i+1], cv2.COLOR_RGB2BGR), NEW_SIZE, interpolation=cv2.INTER_CUBIC)
out.write(frame1)
for alpha in [0.25, 0.5, 0.75]:
out.write(cv2.addWeighted(frame1, 1 - alpha, frame2, alpha, 0))
out.write(cv2.resize(cv2.cvtColor(vid[-1], cv2.COLOR_RGB2BGR), NEW_SIZE, interpolation=cv2.INTER_CUBIC))
out.release()
print(f"[+] Готово! Шизо-видео успешно обработано и сохранено в: {output_path}")
# ИСПОЛЬЗОВАНИЕ
# замени имя файла на свое входное видео
process_user_video("video.mp4")