ThreadAbort commited on
Commit
4c38863
·
1 Parent(s): 3069fab

[Update]: Refined app.py for enhanced GPU handling and memory operations 🌟

Browse files

- Added: Functions to initialize device settings and manage GPU optimizations for Stable Diffusion.
- Updated: MemoryWave and EmotionalContext classes to support dynamic device management.
- Improved: Gradio interface to utilize GPU capabilities more effectively during memory operations.
- Pro Tip of the Commit: When it comes to memory waves, let’s keep the flow smooth and the devices ready! 🌊🚀
Aye, Aye! 🚢

Files changed (1) hide show
  1. app.py +175 -117
app.py CHANGED
@@ -10,7 +10,6 @@ and interact like waves in an ocean of consciousness.
10
 
11
  Created by: Aye & Hue (with Trisha from Accounting keeping the numbers flowing)
12
  """
13
- import spaces
14
  import os
15
  import gradio as gr
16
  import torch
@@ -39,58 +38,67 @@ EMOTION_RANGE = (-5, 5) # Range for emotional valence
39
  AROUSAL_RANGE = (0, 255) # Range for arousal
40
  MAX_SEED = 999999999 # Maximum seed value for art generation
41
 
42
- # Configure device - Use Zero GPU if available
43
- if torch.cuda.is_available():
44
- print("🚀 Zero GPU detected! Enabling hardware acceleration...")
45
- device = "cuda"
46
- # Enable Zero GPU optimizations
47
- torch.backends.cuda.matmul.allow_tf32 = True
48
- torch.backends.cudnn.allow_tf32 = True
49
- torch.backends.cudnn.benchmark = True
50
- else:
51
- print("⚡ Running on CPU")
52
- device = "cpu"
53
-
54
- # Try to import Stable Diffusion components
55
  STABLE_DIFFUSION_AVAILABLE = False
56
  pipe = None
57
- try:
58
- from diffusers import DiffusionPipeline, FlowMatchEulerDiscreteScheduler
59
- STABLE_DIFFUSION_AVAILABLE = True
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
- # Initialize Stable Diffusion pipeline with Zero GPU optimizations
62
  try:
63
- model_id = "stabilityai/stable-diffusion-xl-base-1.0"
64
- print(f"Loading Stable Diffusion model: {model_id}")
65
 
66
- # Always use float32 for CPU, only use float16 for GPU
67
- model_dtype = torch.float16 if device == "cuda" else torch.float32
68
-
69
- pipe = DiffusionPipeline.from_pretrained(
70
- model_id,
71
- torch_dtype=model_dtype,
72
- use_safetensors=True,
73
- variant="fp16" if device == "cuda" else None
74
- )
75
- pipe.scheduler = FlowMatchEulerDiscreteScheduler.from_config(pipe.scheduler.config)
76
- pipe.to(device)
77
-
78
- # Enable memory optimizations only on GPU
79
- if device == "cuda":
80
- pipe.enable_model_cpu_offload()
81
- pipe.enable_vae_slicing()
82
- pipe.enable_vae_tiling()
83
- pipe.enable_attention_slicing(slice_size="max")
84
- print("✨ Stable Diffusion loaded with GPU optimizations")
85
- else:
86
- print("✨ Stable Diffusion loaded in CPU mode")
87
 
88
- except Exception as e:
89
- print(f"⚠️ Warning: Failed to initialize Stable Diffusion: {e}")
90
- STABLE_DIFFUSION_AVAILABLE = False
91
- pipe = None
92
- except ImportError:
93
- print("⚠️ Warning: diffusers package not available. Artistic visualization will be disabled.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
  # Create a directory for memory snapshots if it doesn't exist
96
  MEMORY_DIR = "memory_snapshots"
@@ -106,12 +114,12 @@ class EmotionalContext:
106
  context (torch.Tensor): Contextual flags (16-bit in paper)
107
  safety (torch.Tensor): Psychological safety indicator
108
  """
109
- def __init__(self, device="cuda" if torch.cuda.is_available() else "cpu"):
110
- self.device = device
111
- self.valence = torch.zeros(1).to(device) # -128 to 127: negative to positive
112
- self.arousal = torch.zeros(1).to(device) # 0 to 255: intensity level
113
- self.context = torch.zeros(1).to(device) # Contextual flags
114
- self.safety = torch.ones(1).to(device) # Psychological safety indicator
115
 
116
  # Track emotional history for visualization
117
  self.history = {
@@ -162,6 +170,15 @@ class EmotionalContext:
162
  """String representation of emotional context."""
163
  return f"EmotionalContext(valence={self.valence.item():.2f}, arousal={self.arousal.item():.2f})"
164
 
 
 
 
 
 
 
 
 
 
165
  class MemoryWave:
166
  """
167
  Implements the wave-based memory patterns from Mem|8 paper.
@@ -171,26 +188,26 @@ class MemoryWave:
171
  """
172
  def __init__(self,
173
  size: int = DEFAULT_GRID_SIZE,
174
- device: str = device): # Use global device
175
  """
176
  Initialize a memory wave system.
177
 
178
  Args:
179
  size: Size of the memory grid (NxN)
180
- device: Device to use for computations
181
  """
182
  self.size = size
183
- self.device = device
184
- self.grid = torch.zeros((size, size), device=device)
185
- self.emotion = EmotionalContext(device)
186
 
187
  # Initialize coordinates for wave calculations
188
- self.x = torch.linspace(0, 2*np.pi, size, device=device)
189
- self.y = torch.linspace(0, 2*np.pi, size, device=device)
190
  self.X, self.Y = torch.meshgrid(self.x, self.y, indexing='ij')
191
 
192
  # Memory storage for different types
193
- self.memory_types = {i: torch.zeros((size, size), device=device) for i in range(6)}
194
 
195
  # History of wave states for animation
196
  self.history = []
@@ -488,7 +505,7 @@ class MemoryWave:
488
  "arousal": self.emotion.arousal.item(),
489
  }
490
  }
491
- @spaces.GPU(duration=10)
492
  def generate_memory_reconstruction(self,
493
  emotion_valence: float,
494
  corruption_level: float = 0.3) -> Dict:
@@ -735,51 +752,8 @@ class MemoryWave:
735
 
736
  return filepath
737
 
738
- def generate_memory_prompt(operation: str, emotion_valence: float) -> str:
739
- """Generate an artistic prompt based on the memory operation and emotional context."""
740
-
741
- # Base prompts for each operation type
742
- operation_prompts = {
743
- "wave_memory": "A serene ocean of consciousness with rippling waves of memory, ",
744
- "interference": "Multiple waves of thought intersecting and creating intricate patterns, ",
745
- "resonance": "Harmonious waves of memory resonating with emotional energy, ",
746
- "reconstruction": "Fragments of memory waves reforming into a complete pattern, ",
747
- "hot_tub": "A safe sanctuary of gentle memory waves with healing energy, "
748
- }
749
-
750
- # Emotional modifiers based on valence
751
- if emotion_valence < -3:
752
- emotion_desc = "dark and turbulent, with deep indigo and violet hues, expressing profound melancholy"
753
- elif emotion_valence < -1:
754
- emotion_desc = "muted and somber, with cool blues and grays, showing gentle sadness"
755
- elif emotion_valence < 1:
756
- emotion_desc = "balanced and neutral, with soft pastels, reflecting calm contemplation"
757
- elif emotion_valence < 3:
758
- emotion_desc = "warm and uplifting, with golden yellows and soft oranges, radiating joy"
759
- else:
760
- emotion_desc = "brilliant and ecstatic, with vibrant rainbow colors, bursting with happiness"
761
-
762
- # Artistic style modifiers
763
- style = (
764
- "digital art in the style of a quantum visualization, "
765
- "highly detailed, smooth gradients, "
766
- "abstract yet meaningful, "
767
- "inspired by neural networks and consciousness"
768
- )
769
-
770
- # Combine all elements
771
- base_prompt = operation_prompts.get(operation, operation_prompts["wave_memory"])
772
- prompt = f"{base_prompt}{emotion_desc}, {style}"
773
-
774
- return prompt
775
-
776
- @spaces.GPU(duration=30)
777
- def create_interface():
778
- """Create the Gradio interface for the Mem|8 Wave Memory Explorer."""
779
- # Initialize with Zero GPU device
780
- memory_wave = MemoryWave(device=device)
781
-
782
  def process_memory_operation(
 
783
  operation: str,
784
  emotion_valence: float,
785
  grid_size: int = DEFAULT_GRID_SIZE,
@@ -791,40 +765,40 @@ def create_interface():
791
  """Process a memory operation and return visualizations."""
792
 
793
  # Resize grid if needed
794
- if grid_size != memory_wave.size:
795
- memory_wave.__init__(size=grid_size)
796
 
797
  # Process based on operation type
798
  if operation == "wave_memory":
799
- result = memory_wave.generate_wave_memory(emotion_valence)
800
  wave_title = "Wave Memory Pattern"
801
  wave_data = result["wave"]
802
 
803
  elif operation == "interference":
804
- result = memory_wave.generate_interference_pattern(emotion_valence)
805
  wave_title = "Interference Pattern"
806
  wave_data = result["wave"]
807
 
808
  elif operation == "resonance":
809
- result = memory_wave.generate_resonance_pattern(emotion_valence)
810
  wave_title = "Resonance Pattern"
811
  wave_data = result["wave"]
812
 
813
  elif operation == "reconstruction":
814
- result = memory_wave.generate_memory_reconstruction(emotion_valence)
815
  wave_title = "Memory Reconstruction"
816
  wave_data = result["reconstructed"]
817
 
818
  elif operation == "hot_tub":
819
- result = memory_wave.generate_hot_tub_simulation(
820
  emotion_valence, comfort_level, exploration_depth
821
  )
822
  wave_title = "Hot Tub Exploration"
823
  wave_data = result["safe_result"]
824
 
825
  # Create visualizations
826
- wave_plot = memory_wave.visualize_wave_pattern(wave_data, wave_title)
827
- emotion_plot = memory_wave.visualize_emotional_history()
828
 
829
  # Generate artistic visualization if requested
830
  art_output = None
@@ -852,11 +826,92 @@ def create_interface():
852
  metrics_str += f"• Arousal: {result['emotion']['arousal']:.2f}\n"
853
 
854
  # Save memory snapshot
855
- snapshot_path = memory_wave.save_memory_snapshot(operation)
856
  metrics_str += f"\n💾 Memory snapshot saved: {snapshot_path}"
857
 
858
  return metrics_str, wave_plot, emotion_plot, art_output
859
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
860
  # Create the interface
861
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="purple", secondary_hue="blue")) as demo:
862
  gr.Markdown("""
@@ -939,7 +994,7 @@ def create_interface():
939
 
940
  # Set up event handlers
941
  run_btn.click(
942
- process_memory_operation,
943
  inputs=[
944
  operation_input,
945
  emotion_input,
@@ -974,6 +1029,9 @@ if __name__ == "__main__":
974
  # Configure Gradio for Hugging Face Spaces
975
  demo = create_interface()
976
 
 
 
 
977
  # Enable queuing for better resource management
978
  demo.queue(max_size=10)
979
 
 
10
 
11
  Created by: Aye & Hue (with Trisha from Accounting keeping the numbers flowing)
12
  """
 
13
  import os
14
  import gradio as gr
15
  import torch
 
38
  AROUSAL_RANGE = (0, 255) # Range for arousal
39
  MAX_SEED = 999999999 # Maximum seed value for art generation
40
 
41
+ # Initialize everything for GPU by default
42
+ device = "cuda" if torch.cuda.is_available() else "cpu"
 
 
 
 
 
 
 
 
 
 
 
43
  STABLE_DIFFUSION_AVAILABLE = False
44
  pipe = None
45
+
46
+ def get_device():
47
+ """Get the appropriate device for the current context."""
48
+ if torch.cuda.is_available():
49
+ return "cuda"
50
+ print("⚠️ Warning: CUDA not available, falling back to CPU")
51
+ return "cpu"
52
+
53
+ def init_stable_diffusion(device_str: str = None):
54
+ """Initialize Stable Diffusion optimized for GPU usage."""
55
+ global STABLE_DIFFUSION_AVAILABLE, pipe
56
+
57
+ # Always try to use CUDA if available
58
+ if device_str is None:
59
+ device_str = get_device()
60
 
 
61
  try:
62
+ from diffusers import DiffusionPipeline, FlowMatchEulerDiscreteScheduler
63
+ STABLE_DIFFUSION_AVAILABLE = True
64
 
65
+ try:
66
+ model_id = "stabilityai/stable-diffusion-xl-base-1.0"
67
+ print(f"🚀 Loading Stable Diffusion model: {model_id}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
+ if device_str == "cuda":
70
+ print("🎮 Initializing with GPU optimizations...")
71
+ pipe = DiffusionPipeline.from_pretrained(
72
+ model_id,
73
+ torch_dtype=torch.float16,
74
+ use_safetensors=True,
75
+ variant="fp16"
76
+ )
77
+ pipe.to(device_str)
78
+ # Enable all GPU optimizations
79
+ pipe.enable_model_cpu_offload()
80
+ pipe.enable_vae_slicing()
81
+ pipe.enable_vae_tiling()
82
+ pipe.enable_attention_slicing(slice_size="max")
83
+ print("✨ Stable Diffusion loaded with full GPU optimizations")
84
+ else:
85
+ print("⚠️ CUDA not available - Stable Diffusion may be slow")
86
+ pipe = DiffusionPipeline.from_pretrained(
87
+ model_id,
88
+ torch_dtype=torch.float32,
89
+ use_safetensors=True
90
+ )
91
+ pipe.to("cpu")
92
+
93
+ # Set scheduler
94
+ pipe.scheduler = FlowMatchEulerDiscreteScheduler.from_config(pipe.scheduler.config)
95
+
96
+ except Exception as e:
97
+ print(f"❌ Failed to initialize Stable Diffusion: {e}")
98
+ STABLE_DIFFUSION_AVAILABLE = False
99
+ pipe = None
100
+ except ImportError:
101
+ print("❌ diffusers package not available. Artistic visualization will be disabled.")
102
 
103
  # Create a directory for memory snapshots if it doesn't exist
104
  MEMORY_DIR = "memory_snapshots"
 
114
  context (torch.Tensor): Contextual flags (16-bit in paper)
115
  safety (torch.Tensor): Psychological safety indicator
116
  """
117
+ def __init__(self, device_str="cpu"):
118
+ self.device = device_str
119
+ self.valence = torch.zeros(1, device=device_str) # -128 to 127: negative to positive
120
+ self.arousal = torch.zeros(1, device=device_str) # 0 to 255: intensity level
121
+ self.context = torch.zeros(1, device=device_str) # Contextual flags
122
+ self.safety = torch.ones(1, device=device_str) # Psychological safety indicator
123
 
124
  # Track emotional history for visualization
125
  self.history = {
 
170
  """String representation of emotional context."""
171
  return f"EmotionalContext(valence={self.valence.item():.2f}, arousal={self.arousal.item():.2f})"
172
 
173
+ def to(self, device_str):
174
+ """Move the context to a different device."""
175
+ self.device = device_str
176
+ self.valence = self.valence.to(device_str)
177
+ self.arousal = self.arousal.to(device_str)
178
+ self.context = self.context.to(device_str)
179
+ self.safety = self.safety.to(device_str)
180
+ return self
181
+
182
  class MemoryWave:
183
  """
184
  Implements the wave-based memory patterns from Mem|8 paper.
 
188
  """
189
  def __init__(self,
190
  size: int = DEFAULT_GRID_SIZE,
191
+ device_str: str = "cpu"): # Use global device
192
  """
193
  Initialize a memory wave system.
194
 
195
  Args:
196
  size: Size of the memory grid (NxN)
197
+ device_str: Device to use for computations
198
  """
199
  self.size = size
200
+ self.device = device_str
201
+ self.grid = torch.zeros((size, size), device=device_str)
202
+ self.emotion = EmotionalContext(device_str)
203
 
204
  # Initialize coordinates for wave calculations
205
+ self.x = torch.linspace(0, 2*np.pi, size, device=device_str)
206
+ self.y = torch.linspace(0, 2*np.pi, size, device=device_str)
207
  self.X, self.Y = torch.meshgrid(self.x, self.y, indexing='ij')
208
 
209
  # Memory storage for different types
210
+ self.memory_types = {i: torch.zeros((size, size), device=device_str) for i in range(6)}
211
 
212
  # History of wave states for animation
213
  self.history = []
 
505
  "arousal": self.emotion.arousal.item(),
506
  }
507
  }
508
+
509
  def generate_memory_reconstruction(self,
510
  emotion_valence: float,
511
  corruption_level: float = 0.3) -> Dict:
 
752
 
753
  return filepath
754
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755
  def process_memory_operation(
756
+ self,
757
  operation: str,
758
  emotion_valence: float,
759
  grid_size: int = DEFAULT_GRID_SIZE,
 
765
  """Process a memory operation and return visualizations."""
766
 
767
  # Resize grid if needed
768
+ if grid_size != self.size:
769
+ self.__init__(size=grid_size, device=self.device)
770
 
771
  # Process based on operation type
772
  if operation == "wave_memory":
773
+ result = self.generate_wave_memory(emotion_valence)
774
  wave_title = "Wave Memory Pattern"
775
  wave_data = result["wave"]
776
 
777
  elif operation == "interference":
778
+ result = self.generate_interference_pattern(emotion_valence)
779
  wave_title = "Interference Pattern"
780
  wave_data = result["wave"]
781
 
782
  elif operation == "resonance":
783
+ result = self.generate_resonance_pattern(emotion_valence)
784
  wave_title = "Resonance Pattern"
785
  wave_data = result["wave"]
786
 
787
  elif operation == "reconstruction":
788
+ result = self.generate_memory_reconstruction(emotion_valence)
789
  wave_title = "Memory Reconstruction"
790
  wave_data = result["reconstructed"]
791
 
792
  elif operation == "hot_tub":
793
+ result = self.generate_hot_tub_simulation(
794
  emotion_valence, comfort_level, exploration_depth
795
  )
796
  wave_title = "Hot Tub Exploration"
797
  wave_data = result["safe_result"]
798
 
799
  # Create visualizations
800
+ wave_plot = self.visualize_wave_pattern(wave_data, wave_title)
801
+ emotion_plot = self.visualize_emotional_history()
802
 
803
  # Generate artistic visualization if requested
804
  art_output = None
 
826
  metrics_str += f"• Arousal: {result['emotion']['arousal']:.2f}\n"
827
 
828
  # Save memory snapshot
829
+ snapshot_path = self.save_memory_snapshot(operation)
830
  metrics_str += f"\n💾 Memory snapshot saved: {snapshot_path}"
831
 
832
  return metrics_str, wave_plot, emotion_plot, art_output
833
 
834
+ def to(self, device_str):
835
+ """Move the wave system to a different device."""
836
+ self.device = device_str
837
+ self.grid = self.grid.to(device_str)
838
+ self.emotion = self.emotion.to(device_str)
839
+ self.x = self.x.to(device_str)
840
+ self.y = self.y.to(device_str)
841
+ self.X = self.X.to(device_str)
842
+ self.Y = self.Y.to(device_str)
843
+ self.memory_types = {k: v.to(device_str) for k, v in self.memory_types.items()}
844
+ return self
845
+
846
+ def generate_memory_prompt(operation: str, emotion_valence: float) -> str:
847
+ """Generate an artistic prompt based on the memory operation and emotional context."""
848
+
849
+ # Base prompts for each operation type
850
+ operation_prompts = {
851
+ "wave_memory": "A serene ocean of consciousness with rippling waves of memory, ",
852
+ "interference": "Multiple waves of thought intersecting and creating intricate patterns, ",
853
+ "resonance": "Harmonious waves of memory resonating with emotional energy, ",
854
+ "reconstruction": "Fragments of memory waves reforming into a complete pattern, ",
855
+ "hot_tub": "A safe sanctuary of gentle memory waves with healing energy, "
856
+ }
857
+
858
+ # Emotional modifiers based on valence
859
+ if emotion_valence < -3:
860
+ emotion_desc = "dark and turbulent, with deep indigo and violet hues, expressing profound melancholy"
861
+ elif emotion_valence < -1:
862
+ emotion_desc = "muted and somber, with cool blues and grays, showing gentle sadness"
863
+ elif emotion_valence < 1:
864
+ emotion_desc = "balanced and neutral, with soft pastels, reflecting calm contemplation"
865
+ elif emotion_valence < 3:
866
+ emotion_desc = "warm and uplifting, with golden yellows and soft oranges, radiating joy"
867
+ else:
868
+ emotion_desc = "brilliant and ecstatic, with vibrant rainbow colors, bursting with happiness"
869
+
870
+ # Artistic style modifiers
871
+ style = (
872
+ "digital art in the style of a quantum visualization, "
873
+ "highly detailed, smooth gradients, "
874
+ "abstract yet meaningful, "
875
+ "inspired by neural networks and consciousness"
876
+ )
877
+
878
+ # Combine all elements
879
+ base_prompt = operation_prompts.get(operation, operation_prompts["wave_memory"])
880
+ prompt = f"{base_prompt}{emotion_desc}, {style}"
881
+
882
+ return prompt
883
+
884
+ def create_interface():
885
+ """Create the Gradio interface for the Mem|8 Wave Memory Explorer."""
886
+ # Initialize with GPU by default
887
+ device_str = get_device()
888
+ memory_wave = MemoryWave(device_str=device_str)
889
+
890
+ def process_with_gpu(*args, **kwargs):
891
+ """Process operations on GPU with optimized memory handling."""
892
+ device_str = get_device()
893
+
894
+ try:
895
+ # Ensure we're on GPU if available
896
+ if device_str == "cuda" and memory_wave.device != "cuda":
897
+ memory_wave.to("cuda")
898
+ if pipe is not None and pipe.device.type != "cuda":
899
+ pipe.to("cuda")
900
+
901
+ result = memory_wave.process_memory_operation(*args, **kwargs)
902
+ return result
903
+
904
+ except torch.cuda.OutOfMemoryError:
905
+ print("⚠️ GPU out of memory - falling back to CPU")
906
+ memory_wave.to("cpu")
907
+ if pipe is not None:
908
+ pipe.to("cpu")
909
+ return memory_wave.process_memory_operation(*args, **kwargs)
910
+
911
+ except Exception as e:
912
+ print(f"❌ Error during processing: {e}")
913
+ return None
914
+
915
  # Create the interface
916
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="purple", secondary_hue="blue")) as demo:
917
  gr.Markdown("""
 
994
 
995
  # Set up event handlers
996
  run_btn.click(
997
+ process_with_gpu, # Use the wrapped function
998
  inputs=[
999
  operation_input,
1000
  emotion_input,
 
1029
  # Configure Gradio for Hugging Face Spaces
1030
  demo = create_interface()
1031
 
1032
+ # Initialize Stable Diffusion on CPU first
1033
+ init_stable_diffusion("cpu")
1034
+
1035
  # Enable queuing for better resource management
1036
  demo.queue(max_size=10)
1037