github-actions[bot] commited on
Commit
1dda790
·
1 Parent(s): d85f622

Deploy from GitHub - 2026-01-21 11:50:26

Browse files
Files changed (2) hide show
  1. app.py +203 -167
  2. kernels/__init__.py +24 -4
app.py CHANGED
@@ -126,7 +126,11 @@ def get_device():
126
  """
127
  global _device_cache
128
  if _device_cache is None:
129
- if torch.cuda.is_available():
 
 
 
 
130
  _device_cache = torch.device('cuda')
131
  else:
132
  _device_cache = torch.device('cpu')
@@ -734,7 +738,7 @@ def get_blended_model(style1: str, style2: str, alpha: float, backend: str = 'au
734
  # Region-based Style Transfer
735
  # ============================================================================
736
 
737
- def apply_region_style(
738
  image: Image.Image,
739
  mask: Image.Image,
740
  style1: str,
@@ -961,7 +965,7 @@ def get_ai_segmentation_mask(
961
  # Real Style Extraction Training (VGG-based)
962
  # ============================================================================
963
 
964
- def train_custom_style(
965
  style_image: Image.Image,
966
  style_name: str,
967
  num_iterations: int = 100,
@@ -1090,7 +1094,7 @@ def train_custom_style(
1090
  return None, error_msg
1091
 
1092
 
1093
- def extract_style_from_image(
1094
  style_image: Image.Image,
1095
  content_image: Image.Image,
1096
  style_name: str,
@@ -1556,15 +1560,30 @@ def stylize_image_impl(
1556
 
1557
 
1558
  # Wrap with GPU decorator for ZeroGPU if available
1559
- # ZeroGPU requires at least one @GPU function to be present
1560
  if SPACES_AVAILABLE:
1561
  try:
1562
  stylize_image = GPU(stylize_image_impl)
 
 
 
 
 
1563
  except Exception:
1564
  # Fallback if GPU decorator fails
1565
  stylize_image = stylize_image_impl
 
 
 
 
 
1566
  else:
1567
  stylize_image = stylize_image_impl
 
 
 
 
 
1568
 
1569
 
1570
  def process_webcam_frame(image: Image.Image, style: str, backend: str) -> Image.Image:
@@ -1614,7 +1633,7 @@ def process_webcam_frame(image: Image.Image, style: str, backend: str) -> Image.
1614
  return image
1615
 
1616
 
1617
- def apply_region_style_ui(
1618
  input_image: Image.Image,
1619
  mask_type: str,
1620
  position: float,
@@ -1767,7 +1786,7 @@ def run_backend_comparison(style: str) -> str:
1767
  return output
1768
 
1769
 
1770
- def create_style_blend_output(
1771
  input_image: Image.Image,
1772
  style1: str,
1773
  style2: str,
@@ -1802,17 +1821,22 @@ def create_style_blend_output(
1802
 
1803
  custom_css = """
1804
  /* ============================================
1805
- LIQUID GLASS / GLASSMORPHISM THEME
 
1806
  Gradio 5.x Compatible
1807
  ============================================ */
1808
 
 
 
 
1809
  /* Animated gradient background */
1810
  body {
1811
  background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
1812
  background-size: 400% 400%;
1813
  animation: gradientBG 15s ease infinite;
1814
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
1815
  min-height: 100vh;
 
1816
  }
1817
 
1818
  @keyframes gradientBG {
@@ -1823,40 +1847,37 @@ body {
1823
 
1824
  /* Universal font application */
1825
  * {
1826
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
1827
  }
1828
 
1829
- /* Ensure text elements are visible */
1830
- h1, h2, h3, h4, h5, h6, p, span, div, label, button, input, textarea, select {
1831
- color: inherit;
1832
  }
1833
 
1834
- /* Main app container - glass effect */
1835
  .gradio-container {
1836
- backdrop-filter: blur(20px) saturate(180%);
1837
- -webkit-backdrop-filter: blur(20px) saturate(180%);
1838
- background: rgba(255, 255, 255, 0.75) !important;
1839
- border-radius: 24px;
1840
- border: 1px solid rgba(255, 255, 255, 0.3);
1841
- box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.15);
1842
  max-width: 1400px;
1843
- margin: 20px auto;
1844
- padding: 24px !important;
1845
  }
1846
 
1847
- /* Primary button - gradient with glass shimmer */
1848
  button.primary,
1849
  .gr-button-primary,
1850
  [class*="primary"] {
1851
- background: linear-gradient(135deg, rgba(99, 102, 241, 0.9) 0%, rgba(139, 92, 246, 0.9) 100%) !important;
1852
- backdrop-filter: blur(10px);
1853
- border: 1px solid rgba(255, 255, 255, 0.2) !important;
1854
- color: white !important;
1855
  font-weight: 600 !important;
1856
- border-radius: 16px !important;
1857
- padding: 12px 24px !important;
1858
- transition: all 0.3s ease !important;
1859
- box-shadow: 0 4px 15px rgba(99, 102, 241, 0.25) !important;
1860
  position: relative;
1861
  overflow: hidden;
1862
  }
@@ -1864,71 +1885,80 @@ button.primary,
1864
  button.primary:hover,
1865
  .gr-button-primary:hover,
1866
  [class*="primary"]:hover {
 
 
1867
  transform: translateY(-2px);
1868
- box-shadow: 0 8px 25px rgba(99, 102, 241, 0.4) !important;
1869
  }
1870
 
1871
  button.primary:active,
1872
  .gr-button-primary:active,
1873
  [class*="primary"]:active {
1874
- transform: translateY(0);
1875
  }
1876
 
1877
- /* Secondary button - glass style */
1878
  button.secondary,
1879
  .gr-button-secondary,
1880
  .download,
1881
  [class*="secondary"] {
1882
- background: rgba(255, 255, 255, 0.6) !important;
1883
- backdrop-filter: blur(10px);
1884
- border: 1px solid rgba(255, 255, 255, 0.4) !important;
1885
- color: #374151 !important;
1886
- border-radius: 16px !important;
1887
- padding: 10px 20px !important;
1888
- transition: all 0.3s ease !important;
1889
- font-weight: 500 !important;
1890
  }
1891
 
1892
  button.secondary:hover,
1893
  .gr-button-secondary:hover,
1894
  .download:hover,
1895
  [class*="secondary"]:hover {
1896
- background: rgba(255, 255, 255, 0.8) !important;
1897
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1) !important;
 
 
1898
  }
1899
 
1900
- /* All buttons */
1901
  button {
1902
- border-radius: 12px !important;
1903
- transition: all 0.2s ease !important;
 
 
 
1904
  }
1905
 
1906
- /* Tabs - glass style */
1907
  .tabs {
1908
- background: rgba(255, 255, 255, 0.4) !important;
1909
- backdrop-filter: blur(10px);
1910
- border-radius: 16px !important;
1911
- padding: 8px !important;
1912
- border: 1px solid rgba(255, 255, 255, 0.3) !important;
1913
  }
1914
 
1915
  /* Tab buttons */
1916
  button.tab-item {
1917
  background: transparent !important;
1918
- border-radius: 12px !important;
1919
- color: #6B7280 !important;
1920
- transition: all 0.3s ease !important;
 
 
 
1921
  }
1922
 
1923
  button.tab-item:hover {
1924
- background: rgba(255, 255, 255, 0.5) !important;
1925
  }
1926
 
1927
  button.tab-item.selected {
1928
- background: rgba(255, 255, 255, 0.8) !important;
1929
- color: #6366F1 !important;
1930
- font-weight: 600 !important;
1931
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important;
1932
  }
1933
 
1934
  /* Input boxes and text areas */
@@ -1936,99 +1966,106 @@ input[type="text"],
1936
  input[type="number"],
1937
  textarea,
1938
  select {
1939
- background: rgba(255, 255, 255, 0.7) !important;
1940
- backdrop-filter: blur(10px);
1941
- border: 1px solid rgba(255, 255, 255, 0.5) !important;
1942
- border-radius: 12px !important;
1943
- transition: all 0.3s ease !important;
1944
  }
1945
 
1946
  input[type="text"]:focus,
1947
  input[type="number"]:focus,
1948
  textarea:focus,
1949
  select:focus {
1950
- background: rgba(255, 255, 255, 0.9) !important;
1951
- border-color: #6366F1 !important;
1952
- box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1) !important;
1953
  outline: none !important;
 
1954
  }
1955
 
1956
- /* Image containers - glass frame */
1957
  .image-container,
1958
  [class*="image"] {
1959
- border-radius: 16px !important;
1960
- border: 1px solid rgba(255, 255, 255, 0.3) !important;
1961
  overflow: hidden !important;
1962
- background: rgba(255, 255, 255, 0.3) !important;
1963
  }
1964
 
1965
- /* Slider styling */
1966
  input[type="range"] {
1967
  -webkit-appearance: none;
1968
- background: rgba(229, 231, 235, 0.6);
1969
- backdrop-filter: blur(10px);
1970
- border-radius: 8px;
1971
- height: 8px;
1972
- border: 1px solid rgba(255, 255, 255, 0.3);
1973
  }
1974
 
1975
  input[type="range"]::-webkit-slider-thumb {
1976
  -webkit-appearance: none;
1977
- width: 22px;
1978
- height: 22px;
1979
- background: linear-gradient(135deg, #6366F1 0%, #8B5CF6 100%);
1980
- border: 3px solid white;
1981
  border-radius: 50%;
1982
  cursor: pointer;
1983
- box-shadow: 0 2px 8px rgba(99, 102, 241, 0.4);
 
 
 
 
 
1984
  }
1985
 
1986
  input[type="range"]::-moz-range-thumb {
1987
- width: 22px;
1988
- height: 22px;
1989
- background: linear-gradient(135deg, #6366F1 0%, #8B5CF6 100%);
1990
- border: 3px solid white;
1991
  border-radius: 50%;
1992
  cursor: pointer;
1993
- box-shadow: 0 2px 8px rgba(99, 102, 241, 0.4);
 
1994
  }
1995
 
1996
- /* Checkbox and radio styling */
 
 
 
 
1997
  input[type="checkbox"],
1998
  input[type="radio"] {
1999
- accent-color: #6366F1 !important;
2000
- width: 18px !important;
2001
- height: 18px !important;
2002
  }
2003
 
2004
- /* Badge styles */
2005
  .live-badge {
2006
  display: inline-block;
2007
- padding: 6px 16px;
2008
- background: rgba(254, 243, 199, 0.8);
2009
- backdrop-filter: blur(10px);
2010
  color: #92400E;
2011
- border-radius: 24px;
2012
- font-size: 13px;
2013
- font-weight: 600;
2014
- border: 1px solid rgba(255, 255, 255, 0.3);
2015
  }
2016
 
2017
  .backend-badge {
2018
  display: inline-block;
2019
- padding: 6px 16px;
2020
- background: rgba(209, 250, 229, 0.8);
2021
- backdrop-filter: blur(10px);
2022
  color: #065F46;
2023
- border-radius: 24px;
2024
- font-size: 13px;
2025
- font-weight: 600;
2026
- border: 1px solid rgba(255, 255, 255, 0.3);
2027
  }
2028
 
2029
  /* Markdown content */
2030
  .markdown {
2031
- color: #374151 !important;
2032
  }
2033
 
2034
  /* Text visibility fixes */
@@ -2043,7 +2080,7 @@ input[type="radio"] {
2043
  .gradio-container p,
2044
  .gradio-container span,
2045
  .gradio-container label {
2046
- color: #1F2937 !important;
2047
  }
2048
 
2049
  /* Button text colors */
@@ -2056,14 +2093,22 @@ button,
2056
  input,
2057
  textarea,
2058
  select {
2059
- color: #1F2937 !important;
2060
  }
2061
 
2062
- /* Label colors */
2063
  label,
2064
  [class*="label"] {
2065
- color: #374151 !important;
2066
- font-weight: 500 !important;
 
 
 
 
 
 
 
 
2067
  }
2068
 
2069
  /* Gradio 5.x specific text elements */
@@ -2075,79 +2120,76 @@ label,
2075
  .group,
2076
  .row,
2077
  .column {
2078
- background: rgba(255, 255, 255, 0.3) !important;
2079
- border-radius: 16px !important;
2080
- padding: 16px !important;
2081
  }
2082
 
2083
- /* Accordion */
2084
  .details {
2085
- background: rgba(255, 255, 255, 0.4) !important;
2086
- backdrop-filter: blur(10px);
2087
- border-radius: 16px !important;
2088
- border: 1px solid rgba(255, 255, 255, 0.3) !important;
2089
  }
2090
 
2091
- /* Scrollbar - glass style */
2092
  ::-webkit-scrollbar {
2093
- width: 10px;
2094
- height: 10px;
2095
  }
2096
 
2097
  ::-webkit-scrollbar-track {
2098
- background: rgba(229, 231, 235, 0.3);
2099
- border-radius: 8px;
2100
  }
2101
 
2102
  ::-webkit-scrollbar-thumb {
2103
- background: rgba(167, 139, 250, 0.5);
2104
- border-radius: 8px;
2105
- border: 2px solid rgba(255, 255, 255, 0.3);
2106
  }
2107
 
2108
  ::-webkit-scrollbar-thumb:hover {
2109
- background: rgba(139, 92, 246, 0.7);
2110
  }
2111
 
2112
- /* Progress bar */
2113
  progress {
2114
- background: rgba(229, 231, 235, 0.5) !important;
2115
- border-radius: 8px !important;
2116
- height: 8px !important;
2117
  }
2118
 
2119
  progress::-webkit-progress-bar {
2120
- background: rgba(229, 231, 235, 0.5);
2121
- border-radius: 8px;
2122
  }
2123
 
2124
  progress::-webkit-progress-value {
2125
- background: linear-gradient(90deg, #6366F1, #8B5CF6) !important;
2126
- border-radius: 8px;
2127
  }
2128
 
2129
  /* Mobile responsive */
2130
  @media (max-width: 768px) {
2131
  .gradio-container {
2132
- margin: 10px !important;
2133
- padding: 16px !important;
2134
- border-radius: 20px !important;
2135
  }
2136
 
2137
  button.primary,
2138
  .gr-button-primary,
2139
  [class*="primary"] {
2140
- padding: 10px 18px !important;
2141
  font-size: 14px !important;
2142
  }
2143
  }
2144
 
2145
- /* Loading spinner */
2146
  .spinner {
2147
- border: 3px solid rgba(99, 102, 241, 0.2);
2148
- border-top: 3px solid #6366F1;
2149
  border-radius: 50%;
2150
- animation: spin 1s linear infinite;
2151
  }
2152
 
2153
  @keyframes spin {
@@ -2159,19 +2201,18 @@ progress::-webkit-progress-value {
2159
  .gradio-button.primary,
2160
  button[class*="Primary"],
2161
  [type="button"].primary {
2162
- background: linear-gradient(135deg, rgba(99, 102, 241, 0.9) 0%, rgba(139, 92, 246, 0.9) 100%) !important;
2163
- border: 1px solid rgba(255, 255, 255, 0.2) !important;
2164
- color: white !important;
2165
- font-weight: 600 !important;
2166
- border-radius: 16px !important;
2167
- box-shadow: 0 4px 15px rgba(99, 102, 241, 0.25) !important;
2168
  }
2169
 
2170
  /* Block containers */
2171
  .block {
2172
- background: rgba(255, 255, 255, 0.25) !important;
2173
- border-radius: 16px !important;
2174
- padding: 12px !important;
2175
  }
2176
 
2177
  /* Form elements */
@@ -2183,29 +2224,24 @@ button[class*="Primary"],
2183
 
2184
  with gr.Blocks(
2185
  title="StyleForge: Neural Style Transfer",
2186
- theme=gr.themes.Glass(
2187
- primary_hue="indigo",
2188
- secondary_hue="purple",
2189
  font=gr.themes.GoogleFont("Inter"),
2190
- radius_size="lg",
2191
  ),
2192
  css=custom_css,
2193
  ) as demo:
2194
 
2195
- # Header with Portal-style hero section
2196
  cuda_badge = f"<span class='backend-badge'>CUDA Accelerated</span>" if CUDA_KERNELS_AVAILABLE else ""
2197
  gr.Markdown(f"""
2198
- <div style="text-align: center; padding: 3rem 0 2rem 0;">
2199
- <h1 style="font-size: 3rem; margin-bottom: 0.5rem; background: linear-gradient(135deg, #6366F1, #8B5CF6); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-weight: 700;">
2200
  StyleForge
2201
  </h1>
2202
- <p style="color: #6B7280; font-size: 1.1rem; margin-bottom: 1rem;">
2203
  Neural Style Transfer with Custom CUDA Kernels
2204
  </p>
2205
  {cuda_badge}
2206
- <p style="color: #9CA3AF; margin-top: 1rem; font-size: 0.9rem;">
2207
- Custom Styles • Region Transfer • Style Blending • Real-time Processing
2208
- </p>
2209
  </div>
2210
  """)
2211
 
 
126
  """
127
  global _device_cache
128
  if _device_cache is None:
129
+ # On ZeroGPU, always assume CUDA will be available in GPU task
130
+ # Don't call torch.cuda.is_available() at module level
131
+ if _SPACES_ZERO_GPU:
132
+ _device_cache = torch.device('cuda') # Will be resolved in GPU task
133
+ elif torch.cuda.is_available():
134
  _device_cache = torch.device('cuda')
135
  else:
136
  _device_cache = torch.device('cpu')
 
738
  # Region-based Style Transfer
739
  # ============================================================================
740
 
741
+ def apply_region_style_impl(
742
  image: Image.Image,
743
  mask: Image.Image,
744
  style1: str,
 
965
  # Real Style Extraction Training (VGG-based)
966
  # ============================================================================
967
 
968
+ def train_custom_style_impl(
969
  style_image: Image.Image,
970
  style_name: str,
971
  num_iterations: int = 100,
 
1094
  return None, error_msg
1095
 
1096
 
1097
+ def extract_style_from_image_impl(
1098
  style_image: Image.Image,
1099
  content_image: Image.Image,
1100
  style_name: str,
 
1560
 
1561
 
1562
  # Wrap with GPU decorator for ZeroGPU if available
1563
+ # ZeroGPU requires ALL GPU-using functions to be decorated with @GPU
1564
  if SPACES_AVAILABLE:
1565
  try:
1566
  stylize_image = GPU(stylize_image_impl)
1567
+ train_custom_style = GPU(train_custom_style_impl)
1568
+ extract_style_from_image = GPU(extract_style_from_image_impl)
1569
+ create_style_blend_output = GPU(create_style_blend_output_impl)
1570
+ apply_region_style = GPU(apply_region_style_impl)
1571
+ apply_region_style_ui = GPU(apply_region_style_ui_impl)
1572
  except Exception:
1573
  # Fallback if GPU decorator fails
1574
  stylize_image = stylize_image_impl
1575
+ train_custom_style = train_custom_style_impl
1576
+ extract_style_from_image = extract_style_from_image_impl
1577
+ create_style_blend_output = create_style_blend_output_impl
1578
+ apply_region_style = apply_region_style_impl
1579
+ apply_region_style_ui = apply_region_style_ui_impl
1580
  else:
1581
  stylize_image = stylize_image_impl
1582
+ train_custom_style = train_custom_style_impl
1583
+ extract_style_from_image = extract_style_from_image_impl
1584
+ create_style_blend_output = create_style_blend_output_impl
1585
+ apply_region_style = apply_region_style_impl
1586
+ apply_region_style_ui = apply_region_style_ui_impl
1587
 
1588
 
1589
  def process_webcam_frame(image: Image.Image, style: str, backend: str) -> Image.Image:
 
1633
  return image
1634
 
1635
 
1636
+ def apply_region_style_ui_impl(
1637
  input_image: Image.Image,
1638
  mask_type: str,
1639
  position: float,
 
1786
  return output
1787
 
1788
 
1789
+ def create_style_blend_output_impl(
1790
  input_image: Image.Image,
1791
  style1: str,
1792
  style2: str,
 
1821
 
1822
  custom_css = """
1823
  /* ============================================
1824
+ FLOWLINE-INSPIRED MINIMAL THEME
1825
+ Clean, modern, refined
1826
  Gradio 5.x Compatible
1827
  ============================================ */
1828
 
1829
+ /* Import fonts - Inter for UI, plus a distinctive display font */
1830
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap');
1831
+
1832
  /* Animated gradient background */
1833
  body {
1834
  background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
1835
  background-size: 400% 400%;
1836
  animation: gradientBG 15s ease infinite;
1837
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
1838
  min-height: 100vh;
1839
+ color: #09090B;
1840
  }
1841
 
1842
  @keyframes gradientBG {
 
1847
 
1848
  /* Universal font application */
1849
  * {
1850
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
1851
  }
1852
 
1853
+ /* Headings use Space Grotesk for distinctive look */
1854
+ h1, h2, h3, .gradio-container h1, .gradio-container h2, .gradio-container h3 {
1855
+ font-family: 'Space Grotesk', sans-serif !important;
1856
  }
1857
 
1858
+ /* Main app container - clean, minimal */
1859
  .gradio-container {
1860
+ background: #FFFFFF !important;
1861
+ border-radius: 12px;
1862
+ border: 1px solid #E4E4E7;
1863
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
 
 
1864
  max-width: 1400px;
1865
+ margin: 24px auto;
1866
+ padding: 32px !important;
1867
  }
1868
 
1869
+ /* Primary button - bigger with smooth hover animation */
1870
  button.primary,
1871
  .gr-button-primary,
1872
  [class*="primary"] {
1873
+ background: #18181B !important;
1874
+ border: 1px solid #18181B !important;
1875
+ color: #FAFAFA !important;
 
1876
  font-weight: 600 !important;
1877
+ font-size: 16px !important;
1878
+ border-radius: 12px !important;
1879
+ padding: 14px 28px !important;
1880
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
1881
  position: relative;
1882
  overflow: hidden;
1883
  }
 
1885
  button.primary:hover,
1886
  .gr-button-primary:hover,
1887
  [class*="primary"]:hover {
1888
+ background: #000000 !important;
1889
+ border-color: #000000 !important;
1890
  transform: translateY(-2px);
1891
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15) !important;
1892
  }
1893
 
1894
  button.primary:active,
1895
  .gr-button-primary:active,
1896
  [class*="primary"]:active {
1897
+ transform: translateY(0) scale(0.98);
1898
  }
1899
 
1900
+ /* Secondary button - bigger with hover animation */
1901
  button.secondary,
1902
  .gr-button-secondary,
1903
  .download,
1904
  [class*="secondary"] {
1905
+ background: #FFFFFF !important;
1906
+ border: 1px solid #E4E4E7 !important;
1907
+ color: #18181B !important;
1908
+ border-radius: 12px !important;
1909
+ padding: 13px 24px !important;
1910
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
1911
+ font-weight: 600 !important;
1912
+ font-size: 15px !important;
1913
  }
1914
 
1915
  button.secondary:hover,
1916
  .gr-button-secondary:hover,
1917
  .download:hover,
1918
  [class*="secondary"]:hover {
1919
+ background: #FAFAFA !important;
1920
+ border-color: #18181B !important;
1921
+ transform: translateY(-1px);
1922
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08) !important;
1923
  }
1924
 
1925
+ /* All buttons - bigger base size */
1926
  button {
1927
+ border-radius: 10px !important;
1928
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
1929
+ font-size: 15px !important;
1930
+ font-weight: 600 !important;
1931
+ padding: 12px 20px !important;
1932
  }
1933
 
1934
+ /* Tabs - clean style */
1935
  .tabs {
1936
+ background: #FAFAFA !important;
1937
+ border-radius: 8px !important;
1938
+ padding: 4px !important;
1939
+ border: 1px solid #E4E4E7 !important;
 
1940
  }
1941
 
1942
  /* Tab buttons */
1943
  button.tab-item {
1944
  background: transparent !important;
1945
+ border-radius: 6px !important;
1946
+ color: #71717A !important;
1947
+ font-size: 14px !important;
1948
+ font-weight: 500 !important;
1949
+ transition: all 0.15s ease !important;
1950
+ padding: 8px 14px !important;
1951
  }
1952
 
1953
  button.tab-item:hover {
1954
+ background: rgba(0, 0, 0, 0.04) !important;
1955
  }
1956
 
1957
  button.tab-item.selected {
1958
+ background: #FFFFFF !important;
1959
+ color: #18181B !important;
1960
+ font-weight: 500 !important;
1961
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05) !important;
1962
  }
1963
 
1964
  /* Input boxes and text areas */
 
1966
  input[type="number"],
1967
  textarea,
1968
  select {
1969
+ background: #FFFFFF !important;
1970
+ border: 1px solid #E4E4E7 !important;
1971
+ border-radius: 8px !important;
1972
+ transition: all 0.15s ease !important;
1973
+ font-size: 14px !important;
1974
  }
1975
 
1976
  input[type="text"]:focus,
1977
  input[type="number"]:focus,
1978
  textarea:focus,
1979
  select:focus {
1980
+ background: #FFFFFF !important;
1981
+ border-color: #18181B !important;
 
1982
  outline: none !important;
1983
+ box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.05) !important;
1984
  }
1985
 
1986
+ /* Image containers - clean border */
1987
  .image-container,
1988
  [class*="image"] {
1989
+ border-radius: 8px !important;
1990
+ border: 1px solid #E4E4E7 !important;
1991
  overflow: hidden !important;
1992
+ background: #FAFAFA !important;
1993
  }
1994
 
1995
+ /* Slider styling - bigger */
1996
  input[type="range"] {
1997
  -webkit-appearance: none;
1998
+ background: #E4E4E7;
1999
+ border-radius: 4px;
2000
+ height: 6px;
2001
+ border: none;
 
2002
  }
2003
 
2004
  input[type="range"]::-webkit-slider-thumb {
2005
  -webkit-appearance: none;
2006
+ width: 20px;
2007
+ height: 20px;
2008
+ background: #18181B;
2009
+ border: 3px solid #FFFFFF;
2010
  border-radius: 50%;
2011
  cursor: pointer;
2012
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
2013
+ transition: transform 0.2s ease;
2014
+ }
2015
+
2016
+ input[type="range"]::-webkit-slider-thumb:hover {
2017
+ transform: scale(1.1);
2018
  }
2019
 
2020
  input[type="range"]::-moz-range-thumb {
2021
+ width: 20px;
2022
+ height: 20px;
2023
+ background: #18181B;
2024
+ border: 3px solid #FFFFFF;
2025
  border-radius: 50%;
2026
  cursor: pointer;
2027
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
2028
+ transition: transform 0.2s ease;
2029
  }
2030
 
2031
+ input[type="range"]::-moz-range-thumb:hover {
2032
+ transform: scale(1.1);
2033
+ }
2034
+
2035
+ /* Checkbox and radio styling - bigger */
2036
  input[type="checkbox"],
2037
  input[type="radio"] {
2038
+ accent-color: #18181B !important;
2039
+ width: 20px !important;
2040
+ height: 20px !important;
2041
  }
2042
 
2043
+ /* Badge styles - clean, minimal */
2044
  .live-badge {
2045
  display: inline-block;
2046
+ padding: 4px 12px;
2047
+ background: #FEF3C7;
 
2048
  color: #92400E;
2049
+ border-radius: 6px;
2050
+ font-size: 12px;
2051
+ font-weight: 500;
2052
+ border: 1px solid #FDE68A;
2053
  }
2054
 
2055
  .backend-badge {
2056
  display: inline-block;
2057
+ padding: 4px 12px;
2058
+ background: #D1FAE5;
 
2059
  color: #065F46;
2060
+ border-radius: 6px;
2061
+ font-size: 12px;
2062
+ font-weight: 500;
2063
+ border: 1px solid #A7F3D0;
2064
  }
2065
 
2066
  /* Markdown content */
2067
  .markdown {
2068
+ color: #27272A !important;
2069
  }
2070
 
2071
  /* Text visibility fixes */
 
2080
  .gradio-container p,
2081
  .gradio-container span,
2082
  .gradio-container label {
2083
+ color: #27272A !important;
2084
  }
2085
 
2086
  /* Button text colors */
 
2093
  input,
2094
  textarea,
2095
  select {
2096
+ color: #27272A !important;
2097
  }
2098
 
2099
+ /* Label colors - bigger text */
2100
  label,
2101
  [class*="label"] {
2102
+ color: #27272A !important;
2103
+ font-weight: 600 !important;
2104
+ font-size: 15px !important;
2105
+ }
2106
+
2107
+ /* General text size increase */
2108
+ .gradio-container p,
2109
+ .gradio-container span,
2110
+ .gradio-container div {
2111
+ font-size: 15px !important;
2112
  }
2113
 
2114
  /* Gradio 5.x specific text elements */
 
2120
  .group,
2121
  .row,
2122
  .column {
2123
+ background: transparent !important;
2124
+ border-radius: 0 !important;
2125
+ padding: 0 !important;
2126
  }
2127
 
2128
+ /* Accordion - clean */
2129
  .details {
2130
+ background: #FAFAFA !important;
2131
+ border-radius: 8px !important;
2132
+ border: 1px solid #E4E4E7 !important;
 
2133
  }
2134
 
2135
+ /* Scrollbar - minimal */
2136
  ::-webkit-scrollbar {
2137
+ width: 8px;
2138
+ height: 8px;
2139
  }
2140
 
2141
  ::-webkit-scrollbar-track {
2142
+ background: transparent;
 
2143
  }
2144
 
2145
  ::-webkit-scrollbar-thumb {
2146
+ background: #D4D4D8;
2147
+ border-radius: 3px;
 
2148
  }
2149
 
2150
  ::-webkit-scrollbar-thumb:hover {
2151
+ background: #A1A1AA;
2152
  }
2153
 
2154
+ /* Progress bar - minimal */
2155
  progress {
2156
+ background: #E4E4E7 !important;
2157
+ border-radius: 4px !important;
2158
+ height: 4px !important;
2159
  }
2160
 
2161
  progress::-webkit-progress-bar {
2162
+ background: #E4E4E7;
2163
+ border-radius: 4px;
2164
  }
2165
 
2166
  progress::-webkit-progress-value {
2167
+ background: #18181B !important;
2168
+ border-radius: 4px;
2169
  }
2170
 
2171
  /* Mobile responsive */
2172
  @media (max-width: 768px) {
2173
  .gradio-container {
2174
+ margin: 12px !important;
2175
+ padding: 20px !important;
2176
+ border-radius: 12px !important;
2177
  }
2178
 
2179
  button.primary,
2180
  .gr-button-primary,
2181
  [class*="primary"] {
2182
+ padding: 9px 16px !important;
2183
  font-size: 14px !important;
2184
  }
2185
  }
2186
 
2187
+ /* Loading spinner - minimal */
2188
  .spinner {
2189
+ border: 2px solid #E4E4E7;
2190
+ border-top: 2px solid #18181B;
2191
  border-radius: 50%;
2192
+ animation: spin 0.8s linear infinite;
2193
  }
2194
 
2195
  @keyframes spin {
 
2201
  .gradio-button.primary,
2202
  button[class*="Primary"],
2203
  [type="button"].primary {
2204
+ background: #18181B !important;
2205
+ border: 1px solid #18181B !important;
2206
+ color: #FAFAFA !important;
2207
+ font-weight: 500 !important;
2208
+ border-radius: 8px !important;
 
2209
  }
2210
 
2211
  /* Block containers */
2212
  .block {
2213
+ background: transparent !important;
2214
+ border-radius: 0 !important;
2215
+ padding: 0 !important;
2216
  }
2217
 
2218
  /* Form elements */
 
2224
 
2225
  with gr.Blocks(
2226
  title="StyleForge: Neural Style Transfer",
2227
+ theme=gr.themes.Base(
 
 
2228
  font=gr.themes.GoogleFont("Inter"),
2229
+ radius_size="sm",
2230
  ),
2231
  css=custom_css,
2232
  ) as demo:
2233
 
2234
+ # Header - bigger text with Space Grotesk font
2235
  cuda_badge = f"<span class='backend-badge'>CUDA Accelerated</span>" if CUDA_KERNELS_AVAILABLE else ""
2236
  gr.Markdown(f"""
2237
+ <div style="text-align: center; padding: 2.5rem 0 2rem 0;">
2238
+ <h1 style="font-size: 3.5rem; margin-bottom: 0.5rem; color: #18181B; font-weight: 700; letter-spacing: -0.03em; font-family: 'Space Grotesk', sans-serif;">
2239
  StyleForge
2240
  </h1>
2241
+ <p style="color: #71717A; font-size: 1.15rem; margin-bottom: 1rem; font-weight: 400; letter-spacing: -0.01em;">
2242
  Neural Style Transfer with Custom CUDA Kernels
2243
  </p>
2244
  {cuda_badge}
 
 
 
2245
  </div>
2246
  """)
2247
 
kernels/__init__.py CHANGED
@@ -122,9 +122,19 @@ def load_prebuilt_kernels():
122
  kernel_files += list(_PREBUILT_PATH.glob("*.so")) + list(_PREBUILT_PATH.glob("*.pyd"))
123
 
124
  # Try downloading from dataset if not found locally (on ZeroGPU or if CUDA available)
 
125
  if not kernel_files:
126
  print(f"No local pre-compiled kernels found. _ZERO_GPU={_ZERO_GPU}")
127
- if _ZERO_GPU or torch.cuda.is_available():
 
 
 
 
 
 
 
 
 
128
  print("Trying HuggingFace dataset...")
129
  if _download_kernels_from_dataset():
130
  # Check again after download - look in kernels directory
@@ -229,7 +239,12 @@ def compile_kernels():
229
  print("Using pre-compiled CUDA kernels!")
230
  return True
231
 
232
- if not torch.cuda.is_available():
 
 
 
 
 
233
  _KERNELS_COMPILED = True
234
  return False
235
 
@@ -256,8 +271,13 @@ if _ZERO_GPU:
256
  else:
257
  print("No pre-compiled kernels available, using PyTorch GPU fallback")
258
  _KERNELS_COMPILED = True
259
- elif torch.cuda.is_available():
260
- compile_kernels()
 
 
 
 
 
261
 
262
 
263
  __all__ = [
 
122
  kernel_files += list(_PREBUILT_PATH.glob("*.so")) + list(_PREBUILT_PATH.glob("*.pyd"))
123
 
124
  # Try downloading from dataset if not found locally (on ZeroGPU or if CUDA available)
125
+ # IMPORTANT: Don't call torch.cuda.is_available() on ZeroGPU at module level!
126
  if not kernel_files:
127
  print(f"No local pre-compiled kernels found. _ZERO_GPU={_ZERO_GPU}")
128
+ # On ZeroGPU, always try to download without checking CUDA
129
+ # On local, check CUDA first before downloading
130
+ should_download = _ZERO_GPU
131
+ if not _ZERO_GPU:
132
+ try:
133
+ should_download = torch.cuda.is_available()
134
+ except:
135
+ should_download = False
136
+
137
+ if should_download:
138
  print("Trying HuggingFace dataset...")
139
  if _download_kernels_from_dataset():
140
  # Check again after download - look in kernels directory
 
239
  print("Using pre-compiled CUDA kernels!")
240
  return True
241
 
242
+ # Check CUDA availability (safe here since we're not on ZeroGPU)
243
+ try:
244
+ if not torch.cuda.is_available():
245
+ _KERNELS_COMPILED = True
246
+ return False
247
+ except:
248
  _KERNELS_COMPILED = True
249
  return False
250
 
 
271
  else:
272
  print("No pre-compiled kernels available, using PyTorch GPU fallback")
273
  _KERNELS_COMPILED = True
274
+ elif not _ZERO_GPU:
275
+ # On local, check if CUDA is available and compile
276
+ try:
277
+ if torch.cuda.is_available():
278
+ compile_kernels()
279
+ except:
280
+ _KERNELS_COMPILED = True
281
 
282
 
283
  __all__ = [