diff --git a/astro.config.mjs b/astro.config.mjs index 271cf20..d8d63dc 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -60,6 +60,10 @@ const postDates = new Map(); export default defineConfig({ site: 'https://blog.hoelee.com', trailingSlash: 'always', + redirects: { + '/work-with-me': '/about/', + '/zh/work-with-me': '/zh/about/', + }, i18n: { defaultLocale: 'en', locales: ['en', 'zh'], diff --git a/docs/post-guideline.md b/docs/post-guideline.md index 45d1618..ea1ebfe 100644 --- a/docs/post-guideline.md +++ b/docs/post-guideline.md @@ -71,6 +71,11 @@ summary: # [V2 Feature] High-Conversion Dynamic CTA Matrix (Rendered automatically at bottom) dynamicCta: true + +# [V2 Feature] Homepage Stream Separation & Blueprint Mounting +stream: engineering # engineering (default for main list) | creative-lab (GPU/multimodal lab strip) +blueprint: ai-agent-automation # Optional: self-hosted-infrastructure | ai-agent-automation | sme-digital-suite +blueprintLayer: L1-deterministic-orchestration # Optional: L1..L4 layer slug --- ``` @@ -93,9 +98,10 @@ Every technical post follows the 5-phase "Hard Job → Post" narrative: 3. **The Fix / Architecture**: The exact runnable configuration, patch, or state-machine code. 4. **Technical Deep Dive Accordions**: - For long code dumps, verbose config files, or raw logs (>20 lines), wrap them in native HTML `
`: + - **Summary Specification**: `` MUST state the exact deliverable/artifact and line count/scope (e.g. `🔍 View production docker-compose.yml (Traefik v3 + 2GB mem_limit, 42 lines)`). Never use vague text like `View configuration` or `点击展开`. ```html
- 🔍 查看完整的 Docker Compose 配置与网络策略 + 🔍 查看完整的 Docker Compose 配置文件与网络策略 (Traefik v3 + 2GB 内存限制,42 行) ```yaml services: diff --git a/docs/post-publishing-sop-v2.md b/docs/post-publishing-sop-v2.md index 45d1618..ea1ebfe 100644 --- a/docs/post-publishing-sop-v2.md +++ b/docs/post-publishing-sop-v2.md @@ -71,6 +71,11 @@ summary: # [V2 Feature] High-Conversion Dynamic CTA Matrix (Rendered automatically at bottom) dynamicCta: true + +# [V2 Feature] Homepage Stream Separation & Blueprint Mounting +stream: engineering # engineering (default for main list) | creative-lab (GPU/multimodal lab strip) +blueprint: ai-agent-automation # Optional: self-hosted-infrastructure | ai-agent-automation | sme-digital-suite +blueprintLayer: L1-deterministic-orchestration # Optional: L1..L4 layer slug --- ``` @@ -93,9 +98,10 @@ Every technical post follows the 5-phase "Hard Job → Post" narrative: 3. **The Fix / Architecture**: The exact runnable configuration, patch, or state-machine code. 4. **Technical Deep Dive Accordions**: - For long code dumps, verbose config files, or raw logs (>20 lines), wrap them in native HTML `
`: + - **Summary Specification**: `` MUST state the exact deliverable/artifact and line count/scope (e.g. `🔍 View production docker-compose.yml (Traefik v3 + 2GB mem_limit, 42 lines)`). Never use vague text like `View configuration` or `点击展开`. ```html
- 🔍 查看完整的 Docker Compose 配置与网络策略 + 🔍 查看完整的 Docker Compose 配置文件与网络策略 (Traefik v3 + 2GB 内存限制,42 行) ```yaml services: diff --git a/src/components/PostList.astro b/src/components/PostList.astro index 099fe7e..6983446 100644 --- a/src/components/PostList.astro +++ b/src/components/PostList.astro @@ -3,6 +3,7 @@ import type { CollectionEntry } from 'astro:content'; import { getCollection } from 'astro:content'; import { postLang } from '../lib/lang'; import { tagCounts, tagLink } from '../lib/tags'; +import { categoryLabel } from '../lib/categories'; interface Props { posts: CollectionEntry<'posts'>[]; @@ -74,7 +75,7 @@ const thumb = (post: CollectionEntry<'posts'>, w: 400 | 800) => { )} · - {post.data.category} + {categoryLabel(post.data.category, lang)} {post.data.tags.map((t) => { const href = tagLink(t, counts, lang); return href ? {t} : {t}; diff --git a/src/content.config.ts b/src/content.config.ts index 97c2451..28ebe2e 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -41,6 +41,9 @@ const posts = defineCollection({ }).optional(), }).optional(), dynamicCta: z.boolean().default(false), + stream: z.enum(['engineering', 'creative-lab']).default('engineering'), + blueprint: z.enum(['self-hosted-infrastructure', 'ai-agent-automation', 'sme-digital-suite']).optional(), + blueprintLayer: z.string().optional(), }), }); diff --git a/src/content/posts/debugging-remotion-video-jitter.md b/src/content/posts/debugging-remotion-video-jitter.md index b8af4af..0850055 100644 --- a/src/content/posts/debugging-remotion-video-jitter.md +++ b/src/content/posts/debugging-remotion-video-jitter.md @@ -4,6 +4,7 @@ description: "Diagnose audio-reactive background jitter and crossfade flicker in pubDate: 2025-11-26 updatedDate: 2026-10-22 category: engineering +stream: creative-lab tags: ["remotion", "react", "audio-visualizer", "css-animation", "debugging"] ogImage: "/og/debugging-remotion-video-jitter.jpg" banner: "/banners/debugging-remotion-video-jitter.jpg" diff --git a/src/content/posts/from-audio-to-a-4-minute-ai-music-video.md b/src/content/posts/from-audio-to-a-4-minute-ai-music-video.md index d0df97c..9851c44 100644 --- a/src/content/posts/from-audio-to-a-4-minute-ai-music-video.md +++ b/src/content/posts/from-audio-to-a-4-minute-ai-music-video.md @@ -3,6 +3,7 @@ title: "From Audio to a 4-Minute Music Video: Orchestrating Gemini Argon 4, AI D description: "A complete production breakdown of building a 4-minute 1080p anime OP music video (Crescent Bay): AI music generation, Gemini Argon 4 storyboard prompting, iterative image-to-video rerolls, and Filmora VFX editing." pubDate: 2026-10-25 category: case-studies +stream: creative-lab tags: ["ai-video", "music-video", "gemini", "filmora", "face-swapping", "ai-music", "creative-workflows"] ogImage: "/og/from-audio-to-a-4-minute-ai-music-video.jpg" banner: "/banners/from-audio-to-a-4-minute-ai-music-video.jpg" diff --git a/src/content/posts/generating-full-length-songs-with-yue2-comfyui.md b/src/content/posts/generating-full-length-songs-with-yue2-comfyui.md index 355d145..1a5f005 100644 --- a/src/content/posts/generating-full-length-songs-with-yue2-comfyui.md +++ b/src/content/posts/generating-full-length-songs-with-yue2-comfyui.md @@ -3,6 +3,7 @@ title: "Generating Full-Length Songs with YuE2 BF16: Overcoming Duration Limits description: "AI music tools cut off complex tracks mid-sentence. Here is how I solved the 240s duration wall using YuE2 BF16, 295s headroom budgeting, and a 60-song pipeline." pubDate: 2026-10-26 category: tutorials +stream: creative-lab tags: ["ai-music", "yue2", "comfyui", "audio-engineering", "subtitles", "python"] ogImage: "/og/generating-full-length-songs-with-yue2-comfyui.jpg" banner: "/banners/generating-full-length-songs-with-yue2-comfyui.jpg" diff --git a/src/content/posts/generating-subtitles-for-songs-without-timestamps.md b/src/content/posts/generating-subtitles-for-songs-without-timestamps.md index fca12a0..bae2213 100644 --- a/src/content/posts/generating-subtitles-for-songs-without-timestamps.md +++ b/src/content/posts/generating-subtitles-for-songs-without-timestamps.md @@ -3,6 +3,7 @@ title: "Generating Subtitles for Songs That Ship Without Timestamps" description: "AI music tools give you audio and nothing else — no line timings, no karaoke. Here is the pipeline I use to produce LRC and SRT subtitles for 18 songs, why plain transcription fails, and the two bugs that made the lyrics box scroll to the bottom." pubDate: 2026-10-20 category: tutorials +stream: creative-lab tags: ["subtitles", "lrc", "srt", "whisper", "forced-alignment", "ai-music", "python"] ogImage: "/og/generating-subtitles-for-songs-without-timestamps.jpg" banner: "/banners/generating-subtitles-for-songs-without-timestamps.jpg" diff --git a/src/content/posts/how-i-built-an-automated-music-video-pipeline.md b/src/content/posts/how-i-built-an-automated-music-video-pipeline.md index 8b9d60f..a781793 100644 --- a/src/content/posts/how-i-built-an-automated-music-video-pipeline.md +++ b/src/content/posts/how-i-built-an-automated-music-video-pipeline.md @@ -4,6 +4,7 @@ description: 'Explore an automated music video workflow using Remotion, Whisper, pubDate: 2025-04-18 updatedDate: 2026-10-22 category: case-studies +stream: creative-lab tags: ["remotion", "docker", "cdp", "youtube", "automation", "video-generation", "whisper"] ogImage: "/og/how-i-built-an-automated-music-video-pipeline.jpg" banner: "/banners/how-i-built-an-automated-music-video-pipeline.jpg" diff --git a/src/content/posts/how-i-made-my-own-songs-with-suno-ai.md b/src/content/posts/how-i-made-my-own-songs-with-suno-ai.md index ed54315..6ede767 100644 --- a/src/content/posts/how-i-made-my-own-songs-with-suno-ai.md +++ b/src/content/posts/how-i-made-my-own-songs-with-suno-ai.md @@ -3,6 +3,7 @@ title: "How I Made My Own Songs with Suno AI" description: "I wrote the lyrics, tuned the prompts, and shipped seven songs with Suno AI — folk ballads, a kids' tune, an anime-style Heart Sutra. Full workflow + the tracks." pubDate: 2026-09-11 category: case-studies +stream: creative-lab tags: [suno, ai-music, music, lyrics, prompting, ai] ogImage: /og/how-i-made-my-own-songs-with-suno-ai.jpg banner: /banners/how-i-made-my-own-songs-with-suno-ai.jpg diff --git a/src/content/posts/running-ai-video-locally-on-a-12gb-gpu.md b/src/content/posts/running-ai-video-locally-on-a-12gb-gpu.md index 4b40e15..7c32c60 100644 --- a/src/content/posts/running-ai-video-locally-on-a-12gb-gpu.md +++ b/src/content/posts/running-ai-video-locally-on-a-12gb-gpu.md @@ -3,6 +3,7 @@ title: "Running AI Video Locally on a 12 GB GPU: Real Numbers for Wan 2.2 and Se description: "Measured on an RTX 3060: Wan 2.2 TI2V-5B generation, SeedVR2 upscaling, the 1080p resolution trap, and the one command that fixed five failed runs." pubDate: 2026-10-20 category: ai +stream: creative-lab tags: [ai-video, wan, comfyui, seedvr2, local-llm, gpu, cost] ogImage: /og/running-ai-video-locally-on-a-12gb-gpu.jpg banner: /banners/running-ai-video-locally-on-a-12gb-gpu.jpg diff --git a/src/content/posts/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.md b/src/content/posts/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.md index bd58198..d27ad63 100644 --- a/src/content/posts/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.md +++ b/src/content/posts/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.md @@ -3,6 +3,7 @@ title: "Why My AI Songs Kept Losing Their Endings: Running YuE2 on a 12 GB GPU" description: "Twelve Mandarin songs came out exactly 240.000 seconds long with the outros missing. The cause wasn't the lyrics — it was a hard cap, a VRAM ceiling, and a planner that ignores BPM." pubDate: 2026-10-20 category: ai +stream: creative-lab tags: ["yue2", "comfyui", "ai-music", "local-ai", "gpu", "vram", "mandarin"] ogImage: "/og/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.jpg" banner: "/banners/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.jpg" diff --git a/src/content/posts/zh/debugging-remotion-video-jitter.md b/src/content/posts/zh/debugging-remotion-video-jitter.md index b61dd3e..3ed97e3 100644 --- a/src/content/posts/zh/debugging-remotion-video-jitter.md +++ b/src/content/posts/zh/debugging-remotion-video-jitter.md @@ -4,6 +4,7 @@ description: "深入排查 Remotion 音频可视化中背景画面剧烈抽搐 pubDate: 2025-11-26 updatedDate: 2026-10-22 category: engineering +stream: creative-lab tags: ["remotion", "react", "audio-visualizer", "css-animation", "debugging"] ogImage: "/og/zh-debugging-remotion-video-jitter.jpg" banner: "/banners/debugging-remotion-video-jitter.jpg" diff --git a/src/content/posts/zh/docker-reported-exit-0-the-oom-killer-disagreed.md b/src/content/posts/zh/docker-reported-exit-0-the-oom-killer-disagreed.md index a4d5b1e..e9d8936 100644 --- a/src/content/posts/zh/docker-reported-exit-0-the-oom-killer-disagreed.md +++ b/src/content/posts/zh/docker-reported-exit-0-the-oom-killer-disagreed.md @@ -47,7 +47,7 @@ RestartPolicy: always 照字面读,结论就是:进程干净退出了六次,每次都由重启策略续了命。一个长期运行的代理不会自己以状态 0 退出——而「干净退出」重复六次本身是矛盾,不是答案。`ExitCode` 和 `OOMKilled` 恰好是我在这里最信任的两个字段。在这台机器上,两个都是错的。 -## 内核自己留了另一份记录 +## 内核自己留了另一份记录 在 Linux 上,cgroup 的内存击杀由内核记录,哪怕容器运行时的账本没有把它带过来: @@ -124,13 +124,13 @@ dmesg 里这样的记录一共 **6 条**,而 `RestartCount` 正是 **6**。同 线索就在同一轮测试里:`/robots.txt` 返回 200,内部的 `/cdn` 路径返回 400,而两者是同一时刻——说明路由是健康的,只有我自己的请求被过滤。在一台「你同时是客户端」的宿主上,永远不要用裸 curl 做判断:去探一个过滤器会忽略的路径,或者从访问日志里读出一个 200。 -## 如果重来一次 +## 如果重来一次 1. **把「意外停止」加 `ExitCode 0` 当成「去读 dmesg」的指令**,而不是干净退出的证据。重启计数大于零的容器,在证明清白之前都当作内存事故来查。 2. **对 cgroup 高水位告警,而不是只对重启告警。** 重启后那个已经贴着天花板的读数,在通知到达前约十八分钟就告诉我第 7 次击杀要来了。 3. **早点拿到「谁在打我」这个数字。** 一份日志样本里 25,976 个不同 IP 就是全部故事,而我是在看完整条内存曲线之后才找到它。 4. **怀疑容器,别怀疑服务器。** 「服务器内存不够」和「一台 64 GB 的机器上某个容器只有 512 MiB 上限」需要完全不同的应对,而后者你不去看那个上限就根本看不见。 -## 结果 +## 结果 改动之后再没有出现 OOM 击杀,18 分钟后的峰值是 210 MB,而过去每一个周期都会摸到上限——四天里一直悄悄重启公网入口的那七次击杀,也从 dmesg 里消失了。爬虫洪水并没有停,所以我把这个失败形态记进了那套 stack 的运维笔记:**「容器意外停止」+ `exit 0` / `OOMKilled=false` 是一个会误导人的签名**,而在这类平台上,诚实的证据住在内核日志和 cgroup 的高水位里。 diff --git a/src/content/posts/zh/from-audio-to-a-4-minute-ai-music-video.md b/src/content/posts/zh/from-audio-to-a-4-minute-ai-music-video.md index 157060b..555a3d2 100644 --- a/src/content/posts/zh/from-audio-to-a-4-minute-ai-music-video.md +++ b/src/content/posts/zh/from-audio-to-a-4-minute-ai-music-video.md @@ -3,6 +3,7 @@ title: "从一首歌到 4 分钟完整 MV:我如何用 Gemini、AI 生成与 F description: "基于《月牙湾》1080P 高清动漫 OP 制作实录:详解 AI 音乐重构、Gemini Argon 4 提示词分镜规划、文字生图与图生视频多次抽卡调优,以及 Filmora 剪辑与特效合成的真实生产实践。" pubDate: 2026-10-25 category: case-studies +stream: creative-lab tags: ["ai-video", "music-video", "gemini", "filmora", "face-swapping", "ai-music", "creative-workflows"] ogImage: "/og/zh-from-audio-to-a-4-minute-ai-music-video.jpg" banner: "/banners/from-audio-to-a-4-minute-ai-music-video.jpg" diff --git a/src/content/posts/zh/generating-full-length-songs-with-yue2-comfyui.md b/src/content/posts/zh/generating-full-length-songs-with-yue2-comfyui.md index 3948ef6..b5849a8 100644 --- a/src/content/posts/zh/generating-full-length-songs-with-yue2-comfyui.md +++ b/src/content/posts/zh/generating-full-length-songs-with-yue2-comfyui.md @@ -3,6 +3,7 @@ title: "用 YuE2 BF16 生成完整长歌:突破时长限制与音频硬截断" description: "AI 音乐工具常在歌词中途戛然而止。本文详解如何利用 YuE2 BF16、295秒余量预留公式与本地 ComfyUI,成功批量跑出 60 首自然收尾的完整长歌全集。" pubDate: 2026-10-26 category: tutorials +stream: creative-lab tags: ["ai-music", "yue2", "comfyui", "audio-engineering", "subtitles", "python"] ogImage: "/og/zh-generating-full-length-songs-with-yue2-comfyui.jpg" banner: "/banners/generating-full-length-songs-with-yue2-comfyui.jpg" diff --git a/src/content/posts/zh/generating-subtitles-for-songs-without-timestamps.md b/src/content/posts/zh/generating-subtitles-for-songs-without-timestamps.md index c08ed96..54970eb 100644 --- a/src/content/posts/zh/generating-subtitles-for-songs-without-timestamps.md +++ b/src/content/posts/zh/generating-subtitles-for-songs-without-timestamps.md @@ -3,6 +3,7 @@ title: "给没有时间戳的歌曲自动生成字幕" description: "AI 音乐工具只给你音频 —— 没有逐行时间,没有卡拉 OK。这是我给 18 首歌生成 LRC 与 SRT 字幕的完整流程,为什么单纯转写不行,以及让歌词框滚到底的两个 bug。" pubDate: 2026-10-20 category: tutorials +stream: creative-lab tags: ["subtitles", "lrc", "srt", "whisper", "forced-alignment", "ai-music", "python"] ogImage: "/og/zh-generating-subtitles-for-songs-without-timestamps.jpg" banner: "/banners/generating-subtitles-for-songs-without-timestamps.jpg" diff --git a/src/content/posts/zh/how-i-built-an-automated-music-video-pipeline.md b/src/content/posts/zh/how-i-built-an-automated-music-video-pipeline.md index 6e36616..f004495 100644 --- a/src/content/posts/zh/how-i-built-an-automated-music-video-pipeline.md +++ b/src/content/posts/zh/how-i-built-an-automated-music-video-pipeline.md @@ -4,6 +4,7 @@ description: '基于 Remotion、Whisper、Docker 与 Chrome DevTools Protocol pubDate: 2025-04-18 updatedDate: 2026-10-22 category: case-studies +stream: creative-lab tags: ["remotion", "docker", "cdp", "youtube", "automation", "video-generation", "whisper"] ogImage: "/og/zh-how-i-built-an-automated-music-video-pipeline.jpg" banner: "/banners/how-i-built-an-automated-music-video-pipeline.jpg" diff --git a/src/content/posts/zh/how-i-built-the-digikedai-telegram-bot.md b/src/content/posts/zh/how-i-built-the-digikedai-telegram-bot.md index 2f28b77..7f24658 100644 --- a/src/content/posts/zh/how-i-built-the-digikedai-telegram-bot.md +++ b/src/content/posts/zh/how-i-built-the-digikedai-telegram-bot.md @@ -28,7 +28,7 @@ Digi Kedai 销售数字产品——在线课程、电子书、模板——每一 这篇讲的是它是怎么搭起来的——架构、LLM 接线,以及那些各自吃掉我一整个下午的 bug。 -## 为什么企业需要一个这样的机器人 +## 为什么企业需要一个这样的机器人 讲架构之前,先说*为什么*。客服机器人不是噱头——它改变了小生意的经济学: @@ -49,7 +49,7 @@ Digi Kedai 销售数字产品——在线课程、电子书、模板——每一 - **LiteLLM**——一个位于真实模型之前的自托管网关,这样我可以不碰机器人代码就切换供应商或加故障转移。 - **PostgreSQL**——对话与用户记忆存储,与我的 mem0 栈共用。 -## 架构 +## 架构 ``` 顾客 → Telegram/WhatsApp → Cloudflare 隧道 → bot.digikedai.com @@ -112,7 +112,7 @@ LLM 擅长开放式问题,却很不擅长*状态*。所以那些需要可靠 - **在写通道适配器之前先定好 payload 契约。** WhatsApp 的 `m_text` bug 就来自我信任了一个没读过契约的自定义功能。 - **把 webhook 超时当作一等架构**,而不是事后补丁——如果我在第一天就想到确认窗口,重投递循环本可以避免。 -## 结果 +## 结果 现在 NAS 上的一个容器就能跨两个通道(Telegram + WhatsApp)解答顾客问题,按 SKU 或自然语言检索到正确商品,并端到端发放免费试用账号——还有一套约 175 个单元测试覆盖确定性流程、检索和 payload 契约。源码在 [git.hoelee.com/hoelee/digikedai-bot](https://git.hoelee.com/hoelee/digikedai-bot)。 diff --git a/src/content/posts/zh/how-i-made-my-own-songs-with-suno-ai.md b/src/content/posts/zh/how-i-made-my-own-songs-with-suno-ai.md index b43e670..1551cc7 100644 --- a/src/content/posts/zh/how-i-made-my-own-songs-with-suno-ai.md +++ b/src/content/posts/zh/how-i-made-my-own-songs-with-suno-ai.md @@ -3,6 +3,7 @@ title: "我用 Suno AI 做出自己的歌" description: "自己写词、调风格提示词,用 Suno AI 做出七首原创歌曲——民谣、儿歌、动漫风心经。完整工作流 + 可直接播放的成品。" pubDate: 2026-09-11 category: case-studies +stream: creative-lab tags: [suno, ai-music, music, lyrics, prompting, ai] ogImage: /og/zh-how-i-made-my-own-songs-with-suno-ai.jpg banner: /banners/how-i-made-my-own-songs-with-suno-ai.jpg diff --git a/src/content/posts/zh/running-ai-video-locally-on-a-12gb-gpu.md b/src/content/posts/zh/running-ai-video-locally-on-a-12gb-gpu.md index a81ac12..9cf8939 100644 --- a/src/content/posts/zh/running-ai-video-locally-on-a-12gb-gpu.md +++ b/src/content/posts/zh/running-ai-video-locally-on-a-12gb-gpu.md @@ -3,6 +3,7 @@ title: "12GB 显卡跑本地 AI 视频:Wan 2.2 加 SeedVR2 的真实数据" description: "在 RTX 3060 上实测:Wan 2.2 TI2V-5B 生成、SeedVR2 放大、1080p 分辨率陷阱,以及那条让连续五次失败全部通过的命令。" pubDate: 2026-10-20 category: ai +stream: creative-lab tags: [ai-video, wan, comfyui, seedvr2, local-llm, gpu, cost] ogImage: /og/zh-running-ai-video-locally-on-a-12gb-gpu.jpg banner: /banners/running-ai-video-locally-on-a-12gb-gpu.jpg diff --git a/src/content/posts/zh/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.md b/src/content/posts/zh/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.md index 43a6faf..a6a2138 100644 --- a/src/content/posts/zh/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.md +++ b/src/content/posts/zh/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.md @@ -3,6 +3,7 @@ title: "为什么我的 AI 歌曲总是丢结尾:在 12GB 显卡上跑 YuE2" description: "12 首中文歌时长全都恰好 240.000 秒,尾奏不见了。原因不在歌词 —— 是一道硬上限、一堵显存天花板,和一个不看 BPM 的规划器。" pubDate: 2026-10-20 category: ai +stream: creative-lab tags: ["yue2", "comfyui", "ai-music", "local-ai", "gpu", "vram", "mandarin"] ogImage: "/og/zh-yue2-on-a-12gb-gpu-songs-that-lost-their-endings.jpg" banner: "/banners/yue2-on-a-12gb-gpu-songs-that-lost-their-endings.jpg" diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 47ce604..4d03f30 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -62,8 +62,8 @@ const switchLabel = isZh ? 'EN' : '中文'; // Locale-aware nav labels const nav = isZh - ? { posts: '文章', categories: '分类', about: '关于与合作', rss: 'RSS' } - : { posts: 'Posts', categories: 'Categories', about: 'About & Hire', rss: 'RSS' }; + ? { caseStudies: '工程案例', posts: '全部文章', about: '关于与合作' } + : { caseStudies: 'Case Studies', posts: 'All Posts', about: 'Work With Me' }; --- @@ -184,10 +184,9 @@ const nav = isZh whole group onto a second row (`flex-basis: 100%`) instead of letting individual links wrap around the search / language / theme controls. */}