v1.9.144: Sync Verification - Unconditional Heartbeat & Updated Setup Debug String
This commit is contained in:
@@ -154,64 +154,48 @@ class Audio2Motion:
|
||||
return res_kp_seq
|
||||
|
||||
def _update_kp_cond(self, res_kp_seq, idx):
|
||||
# [v1.9.144] Unconditional State Tracking
|
||||
# We process these outside the fix_kp_cond branches to ensure monitoring never stops.
|
||||
last_pose = res_kp_seq[:, idx-1]
|
||||
|
||||
# Calculate current pitch degree (Ditto 3DMM logic)
|
||||
pitch_bins = last_pose[0, 1:67]
|
||||
e_x = np.exp(pitch_bins - np.max(pitch_bins))
|
||||
p_soft = e_x / e_x.sum()
|
||||
pitch_deg = np.sum(p_soft * np.arange(66)) * 3 - 97.5
|
||||
|
||||
self.global_time += 1
|
||||
if self.global_time % 100 == 0:
|
||||
print(f"[Postural HEARTBEAT] Pitch={pitch_deg:.2f}° | Silence={self.silence_frames} | GlobalTime={self.global_time}")
|
||||
|
||||
if self.fix_kp_cond == 0: # 不重置
|
||||
# [v1.9.139] Silence Tracker & Adaptive Logic
|
||||
# Detect silence intensity (Threshold < 0.1 VAD)
|
||||
is_silent = (idx >= res_kp_seq.shape[1]) or (np.mean(res_kp_seq[:, idx-1, :]) < 0.001) # fallback VAD check
|
||||
# Real VAD is better if accessible, but we track frames since last audio here.
|
||||
# In __call__, we reset silence_frames if audio is present.
|
||||
|
||||
# [Method 3: Threshold Boost]
|
||||
# Beyond 50 frames (2s), we ramp noise and step size to counteract EMA stabilization.
|
||||
# 1. Silence Intensity Boost
|
||||
boost_factor = 1.0
|
||||
if self.silence_frames > 50:
|
||||
# Linear ramp up to 1.6x over the next 150 frames
|
||||
boost_factor = min(1.6, 1.0 + (self.silence_frames - 50) * 0.004)
|
||||
|
||||
last_pose = res_kp_seq[:, idx-1]
|
||||
# Base Noise: 0.005 -> 0.008 at full boost
|
||||
noise_scale = 0.005 * boost_factor
|
||||
noise = np.random.normal(0, noise_scale, last_pose.shape).astype(np.float32)
|
||||
|
||||
# [Method 2: Restless Brownian / Postural Shifts]
|
||||
# We add momentum to the random walk so the "wandering" feels like intentional shifting.
|
||||
# 2. Brownian Momentum Logic
|
||||
drift_scales = np.ones_like(last_pose) * (0.0006 * boost_factor)
|
||||
new_drift = np.random.normal(0, drift_scales, last_pose.shape).astype(np.float32)
|
||||
# 0.92 persistence for momentum (Slow, weighted drift)
|
||||
self.brownian_momentum = self.brownian_momentum * 0.92 + new_drift
|
||||
self.brownian_pos += self.brownian_momentum
|
||||
|
||||
# [Method 1: Compound Sine Sway]
|
||||
self.global_time += 1
|
||||
# 3. Compound Sine Sway
|
||||
t = self.global_time
|
||||
# Layer 1: Main Breathing (~15-20 frames)
|
||||
sway_f1 = np.sin(t * 0.04) * 0.002
|
||||
# Layer 2: Micro Jitter/Heartbeat (~3-5 frames)
|
||||
sway_f2 = np.sin(t * 0.25) * 0.0004
|
||||
# Layer 3: Macro Postural Drift (~300 frames)
|
||||
sway_f3 = np.sin(t * 0.005) * 0.0015
|
||||
|
||||
sway = (sway_f1 + sway_f2 + sway_f3).astype(np.float32)
|
||||
current_s_kp = self.s_kp_cond + sway
|
||||
|
||||
# 3. Micro-Brow Jitters (Indices 15, 16, 18)
|
||||
brow_indices = [15, 16, 18]
|
||||
# [v1.9.141] Postural Auto-Correction (Anti-Stall)
|
||||
# Detect if head is stuck in an upward-tilted ("Looking Up") pose.
|
||||
# Pitch indices are 1:67 in the flattened vector.
|
||||
pitch_bins = last_pose[0, 1:67]
|
||||
# Use softmax + weighted sum to get current degree (Ditto 3DMM logic)
|
||||
# Note: scipy.special.softmax isn't imported here, so we do manual softmax
|
||||
e_x = np.exp(pitch_bins - np.max(pitch_bins))
|
||||
p_soft = e_x / e_x.sum()
|
||||
pitch_deg = np.sum(p_soft * np.arange(66)) * 3 - 97.5
|
||||
# 4. Micro-Brow Jitters (Expression Indices 15, 16, 18 -> offset 202)
|
||||
brow_indices = [217, 218, 220]
|
||||
brow_jitter = np.random.normal(0, 0.015 * boost_factor, len(brow_indices)).astype(np.float32)
|
||||
|
||||
# [v1.9.143] Postural Heartbeat (Sampling Pitch)
|
||||
# Unconditional sampling to diagnose failure of v1.142
|
||||
if self.global_time % 100 == 0:
|
||||
print(f"[Postural HEARTBEAT] Pitch={pitch_deg:.2f}° | Silence={self.silence_frames}")
|
||||
|
||||
# If looking up (>0.5 deg) during long silence, start recovery timer
|
||||
# 5. Postural Auto-Correction (Anti-Stall)
|
||||
if self.silence_frames > 50 and pitch_deg > 0.5:
|
||||
self.look_up_timer += 1
|
||||
if self.look_up_timer % 10 == 0:
|
||||
@@ -219,26 +203,19 @@ class Audio2Motion:
|
||||
else:
|
||||
self.look_up_timer = 0
|
||||
|
||||
# Define gravity vector (Pitch gets special treatment during stall)
|
||||
# Default 5% (0.05)
|
||||
gravity_vec = np.ones_like(last_pose) * 0.05
|
||||
if self.look_up_timer > 50:
|
||||
if self.look_up_timer == 51:
|
||||
print(f"[Postural RECOVERY] Pitch stalled at {pitch_deg:.2f}°. Applying 20% Gravity to Pitch.")
|
||||
# Ramp up restoring force to 20% to slowly pull head back to center
|
||||
gravity_vec[0, 1:67] = 0.20
|
||||
|
||||
brow_jitter = np.random.normal(0, 0.015 * boost_factor, (len(brow_indices), 3)).astype(np.float32)
|
||||
|
||||
# 6. Integration
|
||||
next_pose = last_pose + noise
|
||||
# Inject jitter into specific points
|
||||
for i, idx_in_kp in enumerate(brow_indices):
|
||||
if idx_in_kp < next_pose.shape[1]:
|
||||
next_pose[:, idx_in_kp] += brow_jitter[i]
|
||||
next_pose[0, idx_in_kp] += brow_jitter[i]
|
||||
|
||||
# Anchor = Reference + Compound Sway + Brownian Posture
|
||||
anchor = current_s_kp + self.brownian_pos
|
||||
# Use spatially-varying gravity for correction
|
||||
self.kp_cond = next_pose * (1.0 - gravity_vec) + anchor * gravity_vec
|
||||
|
||||
elif self.fix_kp_cond > 0:
|
||||
|
||||
@@ -533,8 +533,8 @@ class MotionStitch:
|
||||
self.fix_exp_a2 = (1 - _a1) + _a1 * _a2
|
||||
self.fix_exp_a3 = _a2
|
||||
|
||||
# [Debug v1.9.72] Verify Code Sync
|
||||
print(f"[AIIA Debug] MotionStitch Setup: v1.9.72. SHAPE DEBUG MODE.")
|
||||
# [Debug v1.9.144] Verify Code Sync
|
||||
print(f"[AIIA Debug] MotionStitch Setup: v1.9.144. LATEST VERSION LOADED.")
|
||||
|
||||
|
||||
if self.drive_eye and self.delta_eye_arr is not None:
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "aiia"
|
||||
description = "The Ultimate AI Audio/Video toolkit for ComfyUI. Features an enhanced Ditto (with optimizations that outperform official demos and other SOTA talking head models in lip-sync accuracy and natural motion), EchoMimic V3 & FLOAT, VibeVoice & CosyVoice 3.0 (Zero-Shot Voice Cloning), Multi-Role Podcast Generation, and a powerful Media Browser."
|
||||
version = "1.9.143"
|
||||
version = "1.9.144"
|
||||
license = {file = "LICENSE"}
|
||||
readme = "README.md"
|
||||
authors = [
|
||||
|
||||
Reference in New Issue
Block a user