<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by CloseX on Medium]]></title>
        <description><![CDATA[Stories by CloseX on Medium]]></description>
        <link>https://medium.com/@closex?source=rss-7368470241a9------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*JqSMHW8nACptTX2vtD94ag.png</url>
            <title>Stories by CloseX on Medium</title>
            <link>https://medium.com/@closex?source=rss-7368470241a9------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Tue, 23 Jun 2026 23:04:06 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@closex/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Best Practices for Setting Up Hexo Multilingual Blogs]]></title>
            <link>https://closex.medium.com/best-practices-for-setting-up-hexo-multilingual-blogs-e43a1f8dd6d6?source=rss-7368470241a9------2</link>
            <guid isPermaLink="false">https://medium.com/p/e43a1f8dd6d6</guid>
            <category><![CDATA[blog]]></category>
            <category><![CDATA[multilingual]]></category>
            <category><![CDATA[hexo]]></category>
            <category><![CDATA[hexojs]]></category>
            <dc:creator><![CDATA[CloseX]]></dc:creator>
            <pubDate>Thu, 12 Dec 2024 04:59:43 GMT</pubDate>
            <atom:updated>2024-12-12T05:00:19.267Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wS3wcF-4O-Z92ChpS81TGA.jpeg" /></figure><h3>Introduction</h3><p>Creating a multilingual Hexo blog isn&#39;t simple, but it&#39;s not as hard as you might imagine! After a few days of tinkering, I&#39;ve summarized a set of clear, understandable steps that should help you easily set up multiple languages. This tutorial focuses particularly on the Butterfly theme, but it will likely also apply to other themes. Whether you&#39;re a Hexo beginner or have been experimenting for a while, this guide should provide some help. Let&#39;s get started!</p><p>The method used on this site involves duplicating the entire site and placing it in the output folder. The benefit is a clearer structure, while the downside is that changes can be more cumbersome to apply.</p><p>Below is the main directory structure:</p><pre>// Configuration files<br>your_hexo_blog<br>├── _config.yml &lt;-- default<br>├── _config-cn.yml<br>├── _config-fr.yml<br>├── _config-jp.yml<br>​<br>// Theme configuration files<br>├── _config.butterfly.yml &lt;-- default<br>├── _config.butterfly-cn.yml<br>├── _config.butterfly-fr.yml<br>├── _config.butterfly-jp.yml<br>​<br>// Main pages folder<br>├── source  &lt;-- default<br>├── source-cn<br>├── source-fr<br>├── source-jp<br>​<br>// New scripts folder<br>├── scripts &lt;-- scripts<br>    ├── config-debug.js<br>    ├── change_path.js</pre><p>Below are some optional files to modify:</p><pre>(basically your theme folder)<br>hexo-theme-butterfly/layout/includes<br>├── footer.pug <br>├── head.pug<br>└── third-party<br>   └── comments<br>       └── twikoo.pug</pre><p>The tools I used are:</p><ul><li>Cursor Agent (Claude 3.5 Sonnet)</li><li>Cursor Chat (GPT-4o)</li></ul><h3>Modifying the config files</h3><p>Add new _config-(language code).yml files.</p><p>For example, for Chinese:</p><pre># Site<br>language: zh-CN<br>​<br># URL<br>## Set your site url here. For example, if you use GitHub Page, set url as &#39;https://username.github.io/project&#39;<br>url: https://example.com/cn<br>root: /cn/<br>​<br># Directory<br>source_dir: source-cn<br>public_dir: cn<br>​<br># Include / Exclude file(s)<br>## include:/exclude: options only apply to the &#39;source/&#39; folder<br>include:<br>exclude:<br>ignore:<br>  - source-jp/<br>  - source-fr/<br>  - source/</pre><p>Keep other parts unchanged. The main modifications are the basic settings.</p><p>When you run hexo s --config _config-cn.yml, you will access localhost:4000/cn/, so you need to adjust the url and root accordingly.</p><h3>Modifying theme configuration</h3><p>I&#39;m using Butterfly 4.13. Although versions 5.0.0 and later made some adjustments to the configuration files, these changes should not significantly affect this tutorial. If you&#39;re using a newer version, refer to the official documentation for any necessary adjustments.</p><p>Add _config.butterfly-(language code).yml.</p><p>For example, for Chinese:</p><pre># Change the Menu to Chinese<br>menu:<br>  # Article[/article]<br>  # List[/list]<br>  # Link[/link]<br>  # About[/overview]<br>   文章:<br>     中文: /tags/ <br>     中文: /archives/ <br>     中文: /analysis/<br>     中文: /sitemap/</pre><p>Keep other parts unchanged. The main modifications are basic configurations.</p><h3>Copying the source folder</h3><p>Duplicate the source folder and rename it to source-(language code).</p><p>Use Cursor&#39;s Composer Agent function to maintain the structure and translate all files under source. I had 64 files total, and the translation took about 20 minutes. Occasionally, you need to confirm manually, but overall, the experience is fine.</p><h3>Adding the scripts folder</h3><p>Create a scripts folder in the root directory and add config-debug.js and change_path.js.</p><p>config-debug.js matches the site configuration file with the theme configuration file (though this solution might not be optimal, it works until we find a better automatic matching method for Hexo configs). change_path.js handles file paths. Both scripts were written by Claude and are usable.</p><p>config-debug.js</p><pre>&#39;use strict&#39;;<br>​<br>hexo.extend.filter.register(&#39;before_generate&#39;, async () =&gt; {<br>  // Check if --config parameter is used<br>  const configArg = process.argv.find(arg =&gt; arg.startsWith(&#39;_config-&#39;));<br>  if (!configArg) return;<br>​<br>  // Extract language code<br>  const langMatch = configArg.match(/config-([a-z]{2,})\.yml$/);<br>  if (!langMatch) return;<br>​<br>  const lang = langMatch[1];<br>  const themeConfigPath = `_config.butterfly-${lang}.yml`;<br>​<br>  // Use Promise to ensure complete loading of the configuration<br>  await new Promise((resolve, reject) =&gt; {<br>    try {<br>      const yaml = require(&#39;js-yaml&#39;);<br>      const fs = require(&#39;fs&#39;);<br>      <br>      // Read file content<br>      const fileContent = fs.readFileSync(themeConfigPath, &#39;utf8&#39;);<br>      <br>      // Parse YAML<br>      const themeConfig = yaml.load(fileContent);<br>      <br>      // Validate the configuration<br>      if (!themeConfig || typeof themeConfig !== &#39;object&#39;) {<br>        throw new Error(&#39;Invalid theme config format&#39;);<br>      }<br>​<br>      // Apply the configuration<br>      hexo.theme.config = themeConfig;<br>      console.log(`Theme config loaded successfully: ${themeConfigPath}`);<br>      <br>      resolve();<br>    } catch (e) {<br>      console.error(`Failed to load theme config: ${themeConfigPath}`, e);<br>      reject(e);<br>    }<br>  });<br>});</pre><p>change_path.js</p><pre>// scripts/resource-path-handler.js<br>&#39;use strict&#39;;<br>​<br>hexo.extend.filter.register(&#39;after_render:html&#39;, function(str, data) {<br>  // Get the config file name from command line arguments<br>  const configFile = process.argv.find(arg =&gt; arg.includes(&#39;config-&#39;) &amp;&amp; arg.endsWith(&#39;.yml&#39;));<br>  if (!configFile) return str;<br>​<br>  // Extract language code<br>  const langMatch = configFile.match(/config-([a-z]{2,})\.yml$/);<br>  if (!langMatch) return str;<br>  <br>  const lang = langMatch[1];<br>  if (lang === &#39;default&#39;) return str;<br>​<br>  // Paths to exclude<br>  const excludePaths = [<br>    &#39;/search.xml&#39;,<br>    &#39;/sitemap.xml&#39;,<br>    &#39;/robots.txt&#39;,<br>    &#39;/feed.xml&#39;,<br>    &#39;http://&#39;,<br>    &#39;https://&#39;,<br>    &#39;data:image&#39;,<br>    &#39;//&#39;,<br>    &#39;ws://&#39;,<br>    &#39;wss://&#39;<br>  ];<br>​<br>  // Process HTML static resource paths<br>  let result = str;<br>​<br>  // General resource path processing rule<br>  const processPath = (match, p1, p2, p3) =&gt; {<br>    // Check if in the exclude list<br>    if (excludePaths.some(exclude =&gt; p2.startsWith(exclude))) {<br>      return match;<br>    }<br>    // Check if the path already contains the language prefix<br>    if (p2.startsWith(`/${lang}/`)) {<br>      return match;<br>    }<br>    // Ensure the path starts with / and is not a relative path<br>    if (p2.startsWith(&#39;/&#39;) &amp;&amp; !p2.startsWith(&#39;//&#39;)) {<br>      return `${p1}/${lang}${p2}${p3}`;<br>    }<br>    return match;<br>  };<br>​<br>  // Handle all possible resource references<br>  const patterns = [<br>    // src attribute (scripts, images, videos, audios, etc.)<br>    {<br>      pattern: /(src=[&quot;&#39;])(\/[^&quot;&#39;]+)([&quot;&#39;])/g<br>    },<br>    // href attribute (stylesheets, links, etc.)<br>    {<br>      pattern: /(href=[&quot;&#39;])(\/[^&quot;&#39;]+)([&quot;&#39;])/g<br>    },<br>    // data-url attribute<br>    {<br>      pattern: /(data-url=[&quot;&#39;])(\/[^&quot;&#39;]+)([&quot;&#39;])/g<br>    },<br>    // content attribute (meta tags)<br>    {<br>      pattern: /(content=[&quot;&#39;])(\/[^&quot;&#39;]+)([&quot;&#39;])/g<br>    },<br>    // Inline styles with URL<br>    {<br>      pattern: /(url\([&quot;&#39;]?)(\/[^&quot;&#39;)]+)([&quot;&#39;]?\))/g<br>    }<br>  ];<br>​<br>  // Apply all patterns<br>  patterns.forEach(({ pattern }) =&gt; {<br>    result = result.replace(pattern, processPath);<br>  });<br>​<br>  return result;<br>});<br>​<br>// Register helper function to manually control resource paths in templates<br>hexo.extend.helper.register(&#39;langPath&#39;, function(path) {<br>  if (!path || typeof path !== &#39;string&#39;) return path;<br>  <br>  const configFile = process.argv.find(arg =&gt; arg.includes(&#39;config-&#39;) &amp;&amp; arg.endsWith(&#39;.yml&#39;));<br>  if (!configFile) return path;<br>  <br>  const langMatch = configFile.match(/config-([a-z]{2,})\.yml$/);<br>  if (!langMatch) return path;<br>  <br>  const lang = langMatch[1];<br>  if (lang === &#39;default&#39;) return path;<br>  <br>  // Check if it&#39;s an excluded path<br>  const excludePaths = [<br>    &#39;/search.xml&#39;,<br>    &#39;/sitemap.xml&#39;,<br>    &#39;/robots.txt&#39;,<br>    &#39;/feed.xml&#39;,<br>    &#39;http://&#39;,<br>    &#39;https://&#39;,<br>    &#39;data:image&#39;,<br>    &#39;//&#39;,<br>    &#39;ws://&#39;,<br>    &#39;wss://&#39;<br>  ];<br>  <br>  if (excludePaths.some(exclude =&gt; path.startsWith(exclude))) {<br>    return path;<br>  }<br>​<br>  // Check if path already includes the language prefix<br>  if (path.startsWith(`/${lang}/`)) {<br>    return path;<br>  }<br>  <br>  return path.startsWith(&#39;/&#39;) ? `/${lang}${path}` : path;<br>});</pre><h3>Optional Content</h3><p>The following components are mainly for optimizing user experience and can be used as needed:</p><h3>footer.pug</h3><p>This is the footer component, mainly used to display copyright, ICP filings, blogrolls, etc. The language switch button can be placed in footer.pug or navbar.pug. For a better user experience, you could implement a JS script: if the user&#39;s browser language is different and a matching language version exists, preload it. If it&#39;s not 404, show a popup asking the user to switch languages.</p><h3>head.pug</h3><p>This is mainly to add language link tags for search engines. Currently, it&#39;s only done for the homepage. In theory, you could write this into the configuration file. To save effort, I did it this way. It works as is.</p><pre>if is_home()<br>  - var fullUrl = config.url<br>  - var baseUrl = fullUrl.replace(/\/(cn|jp|fr)$/, &#39;&#39;)  // Remove language suffix to get the base URL<br>  - var currentLang = fullUrl.match(/\/(cn|jp|fr)$/) ? fullUrl.match(/\/(cn|jp|fr)$/)[1] : &#39;en&#39;  // Get current language<br>  <br>  if currentLang === &#39;cn&#39;<br>    link(rel=&quot;alternate&quot; hreflang=&quot;zh-CN&quot; href=`${baseUrl}/cn`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;en&quot; href=baseUrl)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;ja-JP&quot; href=`${baseUrl}/jp`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;fr&quot; href=`${baseUrl}/fr`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;x-default&quot; href=baseUrl)<br>  else if currentLang === &#39;jp&#39;<br>    link(rel=&quot;alternate&quot; hreflang=&quot;ja-JP&quot; href=`${baseUrl}/jp`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;en&quot; href=baseUrl)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;zh-CN&quot; href=`${baseUrl}/cn`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;fr&quot; href=`${baseUrl}/fr`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;x-default&quot; href=baseUrl)<br>  else if currentLang === &#39;fr&#39;<br>    link(rel=&quot;alternate&quot; hreflang=&quot;fr&quot; href=`${baseUrl}/fr`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;en&quot; href=baseUrl)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;zh-CN&quot; href=`${baseUrl}/cn`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;ja-JP&quot; href=`${baseUrl}/jp`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;x-default&quot; href=baseUrl)<br>  else<br>    link(rel=&quot;alternate&quot; hreflang=&quot;en&quot; href=baseUrl)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;zh-CN&quot; href=`${baseUrl}/cn`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;ja-JP&quot; href=`${baseUrl}/jp`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;fr&quot; href=`${baseUrl}/fr`)<br>    link(rel=&quot;alternate&quot; hreflang=&quot;x-default&quot; href=baseUrl)</pre><h3>twikoo.pug</h3><p>This is mainly for comment integration.</p><p>For example:</p><ul><li>Original post URL: example.com/posts/666.html (with comments)</li><li>Chinese version post URL: example.com/cn/posts/666.html (no comments by default, since comments are based on the post URL)</li></ul><p>By modifying the twikoo.pug configuration, you can show the original post&#39;s comments on the Chinese version, thus sharing comment data across languages. Visitors will see the complete comment history no matter which language version of the article they view.</p><p>Here is the twikoo.pug configuration file. Just copy and paste:</p><pre>- const { envId, region, option } = theme.twikoo<br>- const { use, lazyload, count } = theme.comments<br>- const multi_lang = theme.twikoo &amp;&amp; theme.twikoo.multi_lang_prefix_handling === true<br>- const lang_prefixes = multi_lang ? theme.twikoo.lang_prefixes : null<br>​<br>script.<br>  (() =&gt; {<br>    const getCount = () =&gt; {<br>      const countELement = document.getElementById(&#39;twikoo-count&#39;)<br>      if(!countELement) return<br>      twikoo.getCommentsCount({<br>        envId: &#39;!{envId}&#39;,<br>        region: &#39;!{region}&#39;,<br>        urls: [window.location.pathname],<br>        includeReply: false<br>      }).then(res =&gt; {<br>        countELement.textContent = res[0].count<br>      }).catch(err =&gt; {<br>        console.error(err)<br>      })<br>    }<br>​<br>    const init = () =&gt; {<br>      // Get processed path<br>      let path = window.location.pathname<br>      if (!{multi_lang} &amp;&amp; !{JSON.stringify(lang_prefixes)}) {<br>        const prefixes = !{JSON.stringify(lang_prefixes)}<br>        if (prefixes &amp;&amp; prefixes.length &gt; 0) {<br>          const langRegex = new RegExp(`^/(${prefixes.join(&#39;|&#39;)})/`)<br>          path = path.replace(langRegex, &#39;/&#39;)<br>        }<br>      }<br>​<br>      twikoo.init(Object.assign({<br>        el: &#39;#twikoo-wrap&#39;,<br>        envId: &#39;!{envId}&#39;,<br>        region: &#39;!{region}&#39;,<br>        path: path,<br>        onCommentLoaded: () =&gt; {<br>          btf.loadLightbox(document.querySelectorAll(&#39;#twikoo .tk-content img:not(.tk-owo-emotion)&#39;))<br>        }<br>      }, !{JSON.stringify(option)}))<br>​<br>      !{count ? &#39;GLOBAL_CONFIG_SITE.isPost &amp;&amp; getCount()&#39; : &#39;&#39;}<br>    }<br>​<br>    const loadTwikoo = () =&gt; {<br>      if (typeof twikoo === &#39;object&#39;) setTimeout(init,0)<br>      else getScript(&#39;!{url_for(theme.asset.twikoo)}&#39;).then(init)<br>    }<br>​<br>    if (&#39;!{use[0]}&#39; === &#39;Twikoo&#39; || !!{lazyload}) {<br>      if (!{lazyload}) btf.loadComment(document.getElementById(&#39;twikoo-wrap&#39;), loadTwikoo)<br>      else loadTwikoo()<br>    } else {<br>      window.loadOtherComment = loadTwikoo<br>    }<br>  })()</pre><p>You need to modify the twikoo configuration in each _config.butterfly-(language code).yml file. Set multi_lang_prefix_handling to true.</p><pre># Twikoo<br># https://github.com/imaegoo/twikoo<br>twikoo:<br>  envId: <br>  region: <br>  visitor: false<br>  multi_lang_prefix_handling: true<br>  lang_prefixes:<br>    - cn<br>    - fr<br>    - jp<br>  option:</pre><h3>Summary</h3><p>At this point, we&#39;ve completed all the configuration work for the multilingual blog.</p><p>To test generating static files for all language versions, run the following command:</p><pre>hexo clean &amp;&amp; hexo g &amp;&amp; hexo clean  --config _config-cn.yml &amp;&amp; hexo g --config _config-cn.yml &amp;&amp; hexo clean  --config _config-fr.yml &amp;&amp; hexo g --config _config-fr.yml &amp;&amp; hexo clean  --config _config-jp.yml &amp;&amp; hexo g --config _config-jp.yml</pre><p>You can put this in package.json and then deploy each language version to your server using hexo d as needed.</p><p>After running the above commands, simply deploy each language version of the content to the server according to its configuration file. Now you&#39;ve successfully launched a multilingual Hexo blog!</p><p>If you use frameworks like Next.js, configuring multilingual support is even simpler...</p><p>References:</p><ul><li><a href="https://github.com/jerryc127/butterfly.js.org">https://github.com/jerryc127/butterfly.js.org</a></li><li>original link: <a href="https://blog.closex.org/posts/757625ef/">https://blog.closex.org/posts/757625ef/</a></li></ul><p>Cover From Internet</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e43a1f8dd6d6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Simplest Linux NVIDIA GPU Fan Speed Control Tutorial]]></title>
            <link>https://closex.medium.com/the-simplest-linux-nvidia-gpu-fan-speed-control-tutorial-8d641e9efdff?source=rss-7368470241a9------2</link>
            <guid isPermaLink="false">https://medium.com/p/8d641e9efdff</guid>
            <category><![CDATA[linux]]></category>
            <category><![CDATA[fan-control]]></category>
            <category><![CDATA[nvidia]]></category>
            <dc:creator><![CDATA[CloseX]]></dc:creator>
            <pubDate>Fri, 28 Jun 2024 11:58:55 GMT</pubDate>
            <atom:updated>2024-06-28T11:58:55.838Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i0rh6hN0T-aZhbFyprEKdQ.jpeg" /></figure><h3>Introduction</h3><p>If your Linux server/PC is equipped with an NVIDIA GPU and you need to adjust its fan speed via SSH without a graphical interface, this is the easiest method to achieve your goal. Whether you’re looking to reduce noise, enhance efficiency, or simply keep your hardware cool, this guide will help you get started quickly.</p><p>(No GUI Required,just need SSH)(Perhaps the simplest)</p><p>Script Address: <a href="https://github.com/RoversX/nvidia_fan_control_linux/"><strong>https://github.com/RoversX/nvidia_fan_control_linux/</strong></a></p><p>Blog Article: <a href="https://blog.closex.org/posts/26a7c6ee/">https://blog.closex.org/posts/26a7c6ee/</a></p><h3>Quick Start Guide</h3><h3>Setting Up Your Environment</h3><ol><li>Create a Python Virtual Environment</li></ol><pre>python3 -m venv fan<br>source fan/bin/activate</pre><p>2. Install the pynvml</p><pre>pip3 install pynvml</pre><p>3. Download the Fan Control Script</p><pre>wget https://raw.githubusercontent.com/RoversX/nvidia_fan_control_linux/main/nvidia_fan_control.py</pre><p>4. Modify the script as needed</p><pre># Fan curve parameters<br>temperature_points = [0, 40, 57, 70]<br>fan_speed_points = [27, 40, 80, 100]<br><br># Sleep interval to reduce CPU activity<br>sleep_seconds = 5</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*61AM-DCa9OVFxsSJGLVo_g.png" /></figure><h3>Configure the Script</h3><p>Create a simple fan.sh script to make the start-up process more convenient</p><pre>nano fan.sh</pre><p>In the editor that opens, copy and paste the following content:</p><pre>#!/bin/bash<br><br># Use sudo to elevate privileges and activate the virtual environment<br>sudo bash &lt;&lt;EOF<br>source /home/x/Workspace/fan/bin/activate<br>python /home/x/Workspace/fan/nvidia_fan_control.py<br>deactivate<br>EOF</pre><h3>Start the Fan Control</h3><p>With everything set up, all you need to do is run the following command to start controlling the fan speed:</p><pre>./fan.sh</pre><h3>Output Example</h3><p>After running the script, you will see an output like this:</p><pre>x@x:~$ ./fan.sh<br>[sudo] password for x: <br>============================================================<br>Driver Version: 535.183.01<br>GPU 0: NVIDIA GeForce RTX 2080 Ti<br>Fan Count: 1<br>============================================================<br>Temperature: 42°C<br>Total Curve Point: 4<br>Current Curve Point: 2<br>Previous_Curve_Point: 1<br>Fan_Speed: 45%<br>============================================================<br>Temperature_Delta: 17<br>Fan_Speed_Delta: 40<br>Temperature_Increment: 2<br>Fan_Speed_Increment: 4.705882352941177<br>Previous_Temperature: 42°C<br>Step_Down_Temperature: 37<br>============================================================</pre><p>This output clearly shows the current temperature and fan speed of your GPU, ensuring your device operates under optimal conditions.</p><p>This script was improved based on: <a href="https://github.com/Cippo95/nvidia-fan-control"><strong>https://github.com/Cippo95/nvidia-fan-control</strong></a></p><p>I also use some code from <a href="https://gist.github.com/AlexKordic/65f031b708177a01a002cc19f0d7298c"><strong>https://gist.github.com/AlexKordic/65f031b708177a01a002cc19f0d7298c</strong></a> to reset back to auto fan control.</p><pre>finally:<br> # reset to auto fan control<br> for handle, fan_count in zip(handles, fan_counts):<br> for i in range(fan_count):<br> nvmlDeviceSetDefaultFanSpeed_v2(handle, i)<br> nvmlShutdown()</pre><h3>Conclusion</h3><p>With these steps, you can easily control the fan speed of NVIDIA GPUs on Linux without the need for a graphical interface, making it particularly suitable for remote management and server environments.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8d641e9efdff" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Import a CSV from Umami Cloud to Self-Hosted Umami]]></title>
            <link>https://closex.medium.com/how-to-import-a-csv-from-umami-cloud-to-self-hosted-umami-77aa15427ba7?source=rss-7368470241a9------2</link>
            <guid isPermaLink="false">https://medium.com/p/77aa15427ba7</guid>
            <category><![CDATA[self-hosted]]></category>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[csv-import]]></category>
            <category><![CDATA[umami]]></category>
            <dc:creator><![CDATA[CloseX]]></dc:creator>
            <pubDate>Wed, 29 May 2024 17:20:53 GMT</pubDate>
            <atom:updated>2024-05-29T17:20:53.120Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fk0_G_9ndNLk-rf4VqrR5A.jpeg" /></figure><h3>Introduction</h3><p>Umami offers a user-friendly interface and powerful website analytics, which makes it a popular choice for many developers and website owners. However, when it comes to longer-term data retention and more extensive domain analysis, the free version of Umami Cloud may not be enough. This tutorial will show you how to migrate your data from Umami Cloud to self-hosted Umami.</p><p><a href="https://youtu.be/m3hJ_MJ7Ljo">Youtube Video Tutorial</a></p><p><a href="https://github.com/RoversX/umami-csv-import-script">Github Repository</a></p><p><a href="https://huggingface.co/spaces/RoversX/umami_import">Huggingface Space</a></p><p><a href="https://blog.closex.org/posts/29bdb155/">Read blog for better experience</a></p><h3>Why migrate?</h3><p>The free version of Umami Cloud, while offering convenient hosting, has two distinct limitations:</p><ol><li>Data retention time limitation: data is only retained for one year, after which it will be automatically deleted.</li><li>Domain name usage limitation: a maximum of three domain names can be analyzed.</li></ol><p>Migrating to a self-hosted version is an ideal option for users who want to retain data and analyze multiple projects over time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WPrDSg-cI9Ra4dmn2Uwehw.jpeg" /></figure><h3>Step 1. Export Data</h3><p><strong>Exporting data from Umami Cloud</strong></p><p>In order to transfer the data, you first need to export the csv data from Umami Cloud.</p><ol><li>Log in to your Umami Cloud account.</li><li>Go to the Data Management page and select the website data you need to export.</li><li>Umami will package the selected data and email a download link when it is ready.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DmrdDb9ly2zMQ8eo3xel8w.jpeg" /></figure><h3>Step 2. Data handling</h3><p>Once you have downloaded the CSV files, you will need to process them using a Python script to make sure they are suitable for importing into the database. This script will help you prepare the data and make sure they are suitable for import into the self-deployed version of the database. You can download this script from <a href="https://github.com/RoversX/umami-csv-import-script">GitHub</a> or use <a href="https://huggingface.co/spaces/RoversX/umami_import">Huggingface Space</a>.</p><p>In Umami&#39;s database, there are two main data types involved: website_event and session. A new site instance needs to be created and the old site ID replaced with the new site ID when importing data.</p><pre>pip install pandas</pre><pre>import pandas as pd<br><br># User enter filename and new website id<br>original_csv_file = input(&quot;Please enter the filename of the original CSV file path: &quot;)<br>new_website_id = input(&quot;Please enter the new website ID: &quot;)<br><br># Load the original CSV file<br>df = pd.read_csv(original_csv_file)<br><br># Update the website_id column with the user-provided website ID<br>df[&#39;website_id&#39;] = new_website_id<br><br># Define the columns required for the website_event table<br>website_event_columns = [<br>    &#39;event_id&#39;, &#39;website_id&#39;, &#39;session_id&#39;, &#39;created_at&#39;, &#39;url_path&#39;,<br>    &#39;url_query&#39;, &#39;referrer_path&#39;, &#39;referrer_query&#39;, &#39;referrer_domain&#39;,<br>    &#39;page_title&#39;, &#39;event_type&#39;, &#39;event_name&#39;, &#39;visit_id&#39;<br>]<br><br># Create a new DataFrame for the website_event data with the required columns<br>df_website_event = df[website_event_columns]<br><br># Save the new website_event data to a CSV file<br>df_website_event.to_csv(&#39;website_event.csv&#39;, index=False)<br><br># Define the columns required for the session table<br>session_columns = [<br>    &#39;session_id&#39;, &#39;website_id&#39;, &#39;hostname&#39;, &#39;browser&#39;, &#39;os&#39;, &#39;device&#39;,<br>    &#39;screen&#39;, &#39;language&#39;, &#39;country&#39;, &#39;subdivision1&#39;, &#39;subdivision2&#39;,<br>    &#39;city&#39;, &#39;created_at&#39;<br>]<br><br># Create a new DataFrame for the session data with the required columns<br>df_session = df[session_columns]<br><br># Save the new session data to a CSV file<br>df_session.to_csv(&#39;session.csv&#39;, index=False)<br><br>print(&quot;Successfully generated website_event.csv and session.csv&quot;)</pre><p>Before that, you need to replace your self-deployed Umami&#39;s Website ID with your old Website ID on Umami Cloud. You can find the website id in the settings screen of the website.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DmrdDb9ly2zMQ8eo3xel8w.jpeg" /></figure><p>After you&#39;ve processed the data, you&#39;ll see two files generated, which arewebsite_event.csv and seesion.csv</p><h3>Step 3. Import data</h3><p>Data can be imported via the SQL command line or by using a database management tool such as PG admin. Please refer to the tutorial link below for details on the import process.</p><p>You can try one of these methods:</p><p>Import CSV File into MySQL Table <a href="https://www.mysqltutorial.org/mysql-basics/import-csv-file-mysql-table/">https://www.mysqltutorial.org/mysql-basics/import-csv-file-mysql-table/</a></p><p>Import CSV File Into PostgreSQL Table <a href="https://www.postgresqltutorial.com/postgresql-tutorial/import-csv-file-into-posgresql-table/">https://www.postgresqltutorial.com/postgresql-tutorial/import-csv-file-into-posgresql-table/</a></p><p>You can import website_event first and then import the session. We then switch to PGadmin and select the website_avent form to perform the data import. Once the files have been imported successfully, simply refresh your Mami interface, and you should see the new data appear.Next, we will do the session data import.There may be some issues encountered regarding session_id. In order to resolve this issue,we can directly remove the associated unique indexes via SQL commands.If you have a better way to deal with this or encounter any difficulties,please feel free to leave a message in the comment section below the article.</p><ol><li><strong>Remove Primary Key Constraint</strong>: This will allow duplicate session_id values in the table. Execute the following command:</li></ol><pre>ALTER TABLE session DROP CONSTRAINT session_pkey;</pre><p><strong>2. Remove Unique Index</strong>: Remove the uniqueness constraint on session_id by executing the following command:</p><pre>DROP INDEX session_session_id_key;</pre><p>After removing these constraints, your table will be able to accept duplicate session_id values. However, please note that primary keys and unique indexes are typically used to ensure data integrity and optimize performance, removing them may lead to other issues.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9VkC6F7y9d-JyD4_w2cA8A.jpeg" /></figure><p><strong>Some Basic Commands</strong></p><ol><li>View All Tables in PostgreSQL</li></ol><pre>\dt</pre><p>If you want to see more detailed information (including table size, etc.), you can use:</p><pre>\dt+</pre><p>2. See how many rows are in the database table</p><pre>SELECT COUNT(*) FROM session;</pre><p>3. Delete specific rows</p><p>If you only want to delete rows that meet certain criteria (e.g., delete session data for a website_id)</p><pre>DELETE FROM session WHERE website_id = &#39;425f-95&#39;;</pre><h3>Conclusion</h3><p>Finally, refresh the page again and you will see that all data has been displayed correctly. At this point, your data migration is complete and you are ready to start using the new tracking code.</p><p>It&#39;s worth noting that many users have requested on GitHub that Umami add a feature to import data directly from the interface.I understand that the development team is considering this feature and hope to implement it in the near future.</p><p><a href="https://github.com/umami-software/umami/issues/2653#issuecomment-2040970801">https://github.com/umami-software/umami/issues/2653#issuecomment-2040970801</a></p><p><a href="https://github.com/umami-software/umami/issues/2456">https://github.com/umami-software/umami/issues/2456</a></p><p>Thank you for reading and I hope this was helpful. Feel free to comment and discuss any questions or suggestions.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=77aa15427ba7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Guide to Fix UnsupportedClassVersion Error in Minecraft 1.20.5 Servers]]></title>
            <link>https://closex.medium.com/guide-to-fix-unsupported-class-version-error-in-minecraft-1-20-5-servers-7c46f734525c?source=rss-7368470241a9------2</link>
            <guid isPermaLink="false">https://medium.com/p/7c46f734525c</guid>
            <category><![CDATA[minecraft]]></category>
            <dc:creator><![CDATA[CloseX]]></dc:creator>
            <pubDate>Sun, 28 Apr 2024 15:24:22 GMT</pubDate>
            <atom:updated>2024-04-30T00:24:44.177Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IvaJVrqyNcSQXFA32d9AIQ.jpeg" /></figure><h3>Introduction</h3><p>When attempting to launch a Minecraft 1.20.5 server on Ubuntu, you may encounter a frustrating error: UnsupportedClassVersionError. This issue arises because the server&#39;s main class, net.minecraft.bundler.Main, was compiled with a more recent version of the Java Runtime (class file version 65.0) than is currently installed on your system, which only supports up to class file version 62.0. This guide will help you resolve this error by updating your Java Runtime Environment to a compatible version.</p><pre>CloseX@CloseX:~/minecraft/1.20.5$ java -Xmx1024M -Xms1024M -jar server.jar nogui<br>​<br>Error: LinkageError occurred while loading main class net.minecraft.bundler.Main<br>        java.lang.UnsupportedClassVersionError: net/minecraft/bundler/Main has been compiled by a more recent version of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 62.0</pre><p>This is due to the fact that the latest Minecraft server 1.20.5 requires Java 21.</p><p>You can download 1.20.5 server from <a href="https://www.minecraft.net/en-us/download/server">https://www.minecraft.net/en-us/download/server</a></p><h3>1. Update Repository</h3><p>Use the following command to update the repository.</p><pre>sudo apt update &amp;&amp; sudo apt upgrade -y</pre><h3>2. Install openjdk-21-jre-headless</h3><pre>sudo apt install openjdk-21-jre-headless</pre><p>Let&#39;s try starting the Minecraft server 1.20.5 again.</p><h3>4. Start Server</h3><pre>java -Xmx1024M -Xms1024M -jar server.jar nogui</pre><p>Congratulations and enjoy your game.</p><p><strong>Note: On Debian, openjdk-21-jre-headless is not yet included in the Debian stable repository. However, it can be found in the unstable repository.</strong></p><ol><li><strong>Edit /etc/apt/sources.list file</strong></li></ol><pre>sudo nano /etc/apt/sources.list</pre><ol><li><strong>Add repository</strong></li></ol><pre>deb http://deb.debian.org/debian sid main</pre><ol><li><strong>Click </strong><strong>ctrl+ </strong><strong>o to save file and click </strong><strong>ctrl+</strong><strong>x to exit</strong></li></ol><p>Then update the repository and install openjdk-21-jre-headless</p><h3>Reference</h3><ol><li><a href="https://dannyda.com/2024/04/25/how-to-fix-minecraft-server-1-20-5-linuxgsm-java-error-java-runtime-only-recognizes-class-file-versions-up-to-61-0-on-debian-12/"><strong>https://dannyda.com/2024/04/25/how-to-fix-minecraft-server-1-20-5-linuxgsm-java-error-java-runtime-only-recognizes-class-file-versions-up-to-61-0-on-debian-12/</strong></a></li><li><a href="https://blog.closex.org/posts/20044/index.html"><strong>https://blog.closex.org/posts/20044/index.html</strong></a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7c46f734525c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using Shaders and Mods in Minecraft On Apple Silicon Mac]]></title>
            <link>https://closex.medium.com/using-shaders-and-mods-in-minecraft-on-apple-silicon-mac-d842629f6c15?source=rss-7368470241a9------2</link>
            <guid isPermaLink="false">https://medium.com/p/d842629f6c15</guid>
            <dc:creator><![CDATA[CloseX]]></dc:creator>
            <pubDate>Mon, 26 Feb 2024 23:49:14 GMT</pubDate>
            <atom:updated>2024-02-26T23:49:14.655Z</atom:updated>
            <content:encoded><![CDATA[<h3>Introduction</h3><p>In this guide, we&#39;ll show you how to add shaders and mods to Minecraft on a Mac using the Iris Shaders mod. This approach enhances Minecraft&#39;s visuals and gameplay on Macs, including those with Apple Silicon chips. We&#39;ll cover the installation process, ensuring a visually stunning and smoothly running Minecraft experience. Whether you&#39;re new to mods and shaders or looking to upgrade your Minecraft setup, this concise guide has you covered.</p><p><strong>All the links you need are here:</strong></p><p><strong>Minecraft Java</strong></p><p><a href="https://www.minecraft.net/">Welcome to the Minecraft Official Site</a></p><p><strong>Fabric</strong></p><p><a href="https://fabricmc.net/use/installer/">Installation for Minecraft Launcher</a></p><p><strong>Fabric API</strong></p><p><a href="https://modrinth.com/mod/fabric-api/">Fabric API - Minecraft Mod</a></p><p><strong>Sodium</strong></p><p><a href="https://modrinth.com/mod/sodium">Sodium - Minecraft Mod</a></p><p><strong>Iris</strong></p><p><a href="https://modrinth.com/mod/iris">Iris Shaders - Minecraft Mod</a></p><h3>1. Install Fabric</h3><p>The first step is to install the Fabric Loader. Go to <a href="https://fabricmc.net/use/installer/">https://fabricmc.net/use/installer/</a> and click Download installer (Universal/.JAR) to download the fabric.</p><p>Double-click the .jar package to install the Fabric Loader. Install the specific version or the latest version, depending on your situation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yTB-bRtfi2ROPPauRYwS2Q.png" /></figure><h3>2. Install Necessary Mods</h3><p>After installing Fabric Loader, open <strong>Minecraft Launcher</strong>. You will find there is an <strong>fabri-loader-1.XX.X</strong> , simplly click <strong>Play</strong> to download some necessary packages. If everything is correct, you will be in the game. Now turn off the game and go to <strong>/Library/Application Support/minecraft</strong>.You need to create two new folders, one called mods (put mods here) and one called shaderpacks (put shaders here).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*F-UTE2PCfe_qSWRLtcStgA.png" /></figure><p>Now you need to download:</p><p><strong>Fabric API</strong></p><p><a href="https://modrinth.com/mod/fabric-api/">https://modrinth.com/mod/fabric-api/</a></p><p>The Fabric API is a minimalistic modding toolchain for Minecraft, offering a flexible framework for creating mods. Known for its quick updates and compatibility with new Minecraft versions, it supports both client-side and server-side mods, making it a popular choice in the modding community.</p><p><strong>Sodium</strong></p><p><a href="https://modrinth.com/mod/sodium">https://modrinth.com/mod/sodium</a></p><p>Sodium is a performance optimization mod for Minecraft that significantly improves the game&#39;s frame rates and reduces lag. It&#39;s designed to work with the Fabric mod loader and focuses on optimizing the game&#39;s rendering engine. By rewriting key parts of the game&#39;s graphics engine, Sodium offers a smoother gameplay experience, especially on lower-end hardware. It&#39;s particularly well-regarded for its ability to enhance performance without compromising the game&#39;s visual quality, making it a popular choice among players looking to improve their Minecraft experience.</p><p><strong>Iris</strong></p><p><a href="https://modrinth.com/mod/iris">https://modrinth.com/mod/iris</a></p><p>Iris is a Minecraft mod for using shaders with Fabric, offering compatibility with Sodium for enhanced performance and visuals. It simplifies shader management, allowing advanced lighting and effects.</p><p>Put the downloaded files into the mods folder.</p><pre>CloseX@X mods % tree<br>.<br>├── fabric-api-0.95.3+1.20.4.jar<br>├── iris-mc1.20.4-1.6.14.jar<br>├── litematica-fabric-1.20.4-0.17.0.jar<br>├── malilib-fabric-1.20.4-0.18.0.jar<br>├── reeses_sodium_options-1.7.0+mc1.20.2-build.97.jar<br>├── sodium-extra-0.5.3+mc1.20.2-build.114.jar<br>└── sodium-fabric-mc1.20.3-0.5.5.jar<br><br>1 directory, 7 files</pre><p>After downloading these mods, open the game and check if everything works fine. If there&#39;s an error it&#39;s probably because the Mac isn&#39;t supported or it&#39;s an incompatible version. Choose the right version to download.</p><h3>3. Download Your Shaders Pack(s)</h3><p>Go to <a href="https://modrinth.com/shaders">https://modrinth.com/shaders</a> or <a href="https://minecraftshader.com/">https://minecraftshader.com</a> to download shaders. You need to be aware that these shaders support Macs. Put the shaders you downloaded into shaderpacks. Open your game and click Options --&gt; Video Settings --&gt; Shader Pack, you can now see your shaders. Then click the shader pack you want in the list, click Apply, and Done.</p><h3>4. Enjoy</h3><p>Congratulations and enjoy your game.</p><h3>Reference</h3><ol><li><a href="https://thebreakdown.xyz/how-to-download-install-iris-shaders-in-minecraft/">https://thebreakdown.xyz/how-to-download-install-iris-shaders-in-minecraft/</a></li><li><a href="https://www.minecraft.net/">https://www.minecraft.net/</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d842629f6c15" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GPT-SoVITS for local inference on Intel or Apple Silicon Mac]]></title>
            <link>https://closex.medium.com/gpt-sovits-for-local-inference-on-intel-or-apple-silicon-mac-bc4c949dab55?source=rss-7368470241a9------2</link>
            <guid isPermaLink="false">https://medium.com/p/bc4c949dab55</guid>
            <dc:creator><![CDATA[CloseX]]></dc:creator>
            <pubDate>Sun, 21 Jan 2024 06:08:59 GMT</pubDate>
            <atom:updated>2024-01-21T06:08:59.939Z</atom:updated>
            <content:encoded><![CDATA[<h3>Introduction</h3><p>The GitHub repository for “GPT-SoVITS” is a project focused on voice data processing and text-to-speech (TTS) technology. It highlights the capability of training a good TTS model using as little as one minute of voice data, a method known as “few shot voice cloning.” The project is under the MIT license and involves Python as its primary programming language.</p><p>This tutorial will talk about how to running this project using the CPU under the Mac platform.</p><ul><li><strong>Don’t think about trainning on Mac yet, It’s good enough if they can preprocess and infer. Running LLM might be possible, but if anyone has successfully trained on a Mac (with MPS), please let me know.</strong></li><li><strong>This tutorial mainly talks about the inference process after training and downloading the model to the local machine. I have tested it, and it all works.</strong></li><li><strong>Training related information can be found in the reference videos above, which are very detailed. The dataset is the key, and patience is needed for training.</strong></li></ul><p><strong>MPS Not Supported</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xam7ETyAFIMbT6-rUMKihw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lIHnCpsv1dlJFsnPpInGJg.png" /></figure><p>Project link: <a href="https://github.com/RVC-Boss/GPT-SoVITS">https://github.com/RVC-Boss/GPT-SoVITS</a></p><blockquote><em>This tutorial is for communication and learning purposes only. Please do not use it for illegal, immoral, or unethical purposes.</em></blockquote><blockquote><em>Please ensure that you address any authorization issues related to the dataset on your own. You bear full responsibility for any problems arising from the usage of non-authorized datasets for training, as well as any resulting consequences. The repository and its maintainer, svc develop team, disclaim any association with or liability for the consequences.</em></blockquote><blockquote><em>It is strictly forbidden to use it for any political-related purposes.</em></blockquote><p><strong>Software requirements:</strong></p><ol><li><strong>Homebrew </strong><a href="https://brew.sh/"><strong>https://brew.sh/</strong></a></li><li><strong>VScode (optional)</strong></li><li><strong>Python3.9</strong></li></ol><pre>brew install python3.9</pre><h3>Local Inference</h3><h4>1. Create venv</h4><p>Create a virtual environment</p><pre>python3.9 -m venv myenv #change &#39;myenv&#39; to a different name</pre><h4>2. Enter venv</h4><pre>cd myenv</pre><pre>source bin/activate</pre><h4>3. Download Project</h4><pre>git clone https://github.com/RVC-Boss/GPT-SoVITS.git</pre><p>cd to the project directory</p><h4>4. Download Package</h4><pre>brew install ffmpeg</pre><pre>pip install torch numpy scipy tensorboard librosa==0.9.2 numba==0.56.4 pytorch-lightning gradio==3.14.0 ffmpeg-python onnxruntime tqdm cn2an pypinyin pyopenjtalk g2p_en chardet</pre><p><strong>Additional Requirements</strong></p><p>If you need Chinese ASR (supported by FunASR), install:</p><pre>pip install modelscope torchaudio sentencepiece funasr</pre><p>Note: If you find No module named Just install that package</p><p>You can also use requirements.txt to install, but if there are some problems, just install what I mentioned before.</p><pre>pip install -r requirements.txt # No need to run this</pre><p>Download pretrained models from <a href="https://huggingface.co/lj1995/GPT-SoVITS">GPT-SoVITS Models</a> and place them in GPT_SoVITS/pretrained_models.</p><p>For Chinese ASR (additionally), download models from <a href="https://modelscope.cn/models/damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch/files">Damo ASR Model</a>, <a href="https://modelscope.cn/models/damo/speech_fsmn_vad_zh-cn-16k-common-pytorch/files">Damo VAD Model</a>, and <a href="https://modelscope.cn/models/damo/punc_ct-transformer_zh-cn-common-vocab272727-pytorch/files">Damo Punc Model</a> and place them in tools/damo_asr/models.</p><p>For UVR5 (Vocals/Accompaniment Separation &amp; Reverberation Removal, additionally), download models from <a href="https://huggingface.co/lj1995/VoiceConversionWebUI/tree/main/uvr5_weights">UVR5 Weights</a> and place them in tools/uvr5/uvr5_weights.</p><p>If you want one click package: <a href="https://github.com/RVC-Boss/GPT-SoVITS/issues/4">https://github.com/RVC-Boss/GPT-SoVITS/issues/4</a></p><h4>5. Start WebUI</h4><pre>python web.py</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HkNXXKeJ3ZpjG3A7eks_tw.png" /></figure><h4>6. Choose Models</h4><p>The models are in these two folders, one is the GPT model and the other is the SoVITS model. You should put the file to the right folder</p><p>Click 是否开启TTS推理WebUI</p><p>An error may be reported at this time. You need to modify GPT_SoVITS/inference_webui.py to use CPU inference.</p><pre>├── GPT_weights<br>   └── LeiJun-e15.ckpt<br>├── SoVITS_weights<br>  └── LeiJun_e10_s470.pth</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IWJaN5xZx2GlKh46i6nI5w.png" /></figure><h4>7. Change inference_webui.py</h4><ol><li><strong>Change </strong><strong>CUDA to </strong><strong>CPU</strong></li><li><strong>Change half precision to full precision </strong><strong>model.half() ---&gt; </strong><strong>model.float()</strong></li></ol><p>Processed file: <a href="https://github.com/RoversX/GPT-SoVITS/blob/main/GPT_SoVITS/inference_webui.py">https://github.com/RoversX/GPT-SoVITS/blob/main/GPT_SoVITS/inference_webui.py</a></p><p>Just save the changes and re-run it to run.</p><pre>python web.py</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*p4S_iNFSlVvHbaAeXqk1Lg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*H5Pi56dnzf06TwEq1zC3qQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5rPzuXKbiGZ2Dc6wNtq3sg.png" /><figcaption>Reslut</figcaption></figure><p>Thanks for reading. If there are any questions or better methods in the tutorial, please point them out.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bc4c949dab55" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SO-VITS-SVC 4.0 and 4.1 local inference on Intel/Apple Silicon Mac]]></title>
            <link>https://closex.medium.com/so-vits-svc-4-0-and-4-1-local-inference-on-intel-apple-silicon-mac-b1ef804bb132?source=rss-7368470241a9------2</link>
            <guid isPermaLink="false">https://medium.com/p/b1ef804bb132</guid>
            <category><![CDATA[mac]]></category>
            <category><![CDATA[sovit]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[CloseX]]></dc:creator>
            <pubDate>Fri, 19 Jan 2024 18:32:13 GMT</pubDate>
            <atom:updated>2024-01-19T18:32:40.699Z</atom:updated>
            <content:encoded><![CDATA[<h3>Introduction</h3><p>The SO-VITS-SVC project represents a cutting-edge initiative in the field of voice synthesis and conversion, specifically tailored for applications in singing voice transformation. Leveraging the capabilities of the Variational Inference with adversarial learning (VITS) models, this project offers a platform for users to convert spoken or sung audio into the voice of a different character or person.</p><p>Primarily targeted at enthusiasts in deep learning and voice synthesis, as well as researchers and hobbyists interested in voice manipulation and anime character voice generation, SO-VITS-SVC serves as a practical tool for applying theoretical knowledge in deep learning to real-world scenarios. The project enables users to experiment with various aspects of voice conversion, including timbre, pitch, and rhythm alterations.</p><p>This tutorial will talk about how to running this project using the CPU under the Mac platform.</p><p><strong>This tutorial is based on videos and practice from </strong><a href="https://www.bilibili.com/"><strong>https://www.bilibili.com</strong></a><strong>.</strong> <strong>Below are the reference videos and documents:</strong></p><ul><li><strong>So-VITS-SVC 4.1 Integration Package Complete Guide, created by </strong><a href="https://space.bilibili.com/3493141443250876"><strong>bilibili@羽毛布団</strong></a><strong>. It’s very good.</strong></li><li><a href="https://www.yuque.com/umoubuton/ueupp5"><strong>https://www.yuque.com/umoubuton/ueupp5</strong></a></li><li><strong>Detailed usage record of so-vits-svc 4.1, source: csdn</strong></li><li><a href="https://blog.csdn.net/qq_17766199/article/details/132436306"><strong>https://blog.csdn.net/qq_17766199/article/details/132436306</strong></a></li><li><strong>Don’t think about trainning on Mac yet, It’s good enough if they can preprocess and infer. Running LLM might be possible, but if anyone has successfully trained on a Mac (with MPS), please let me know.</strong></li><li><strong>This tutorial mainly talks about the inference process after training and downloading the model to the local machine. I have tested it, and it all works.</strong></li><li><strong>Training related information can be found in the reference videos above, which are very detailed. The dataset is the key, and patience is needed for training.</strong></li><li><strong>Project link: </strong><a href="https://github.com/svc-develop-team/so-vits-svc"><strong>https://github.com/svc-develop-team/so-vits-svc</strong></a></li></ul><blockquote><em>This tutorial is for communication and learning purposes only. Please do not use it for illegal, immoral, or unethical purposes.</em></blockquote><blockquote><em>Please ensure that you address any authorization issues related to the dataset on your own. You bear full responsibility for any problems arising from the usage of non-authorized datasets for training, as well as any resulting consequences. The repository and its maintainer, svc develop team, disclaim any association with or liability for the consequences.</em></blockquote><blockquote><em>It is strictly forbidden to use it for any political-related purposes.</em></blockquote><p><strong>Software requirements:</strong></p><ol><li><strong>Homebrew </strong><a href="https://brew.sh/"><strong>https://brew.sh/</strong></a></li><li><strong>VScode (optional)</strong></li><li><strong>Python3</strong></li></ol><p><strong>For SO-VITS-SVC 4.0, install So-Vits-SVC-Fork to prevent errors due to missing packages:</strong></p><pre>brew install python-tk@3.11</pre><p><strong>For SO-VITS-SVC 4.1, to prevent incompatibility issues with Python 3.11 when using WebUI:</strong></p><pre>brew install python3.10</pre><p><strong>Choose the model you need; you don’t need to install both versions.</strong></p><h3>SO-VITS-SVC 4.0 Inference</h3><h4>1. Create venv</h4><p>Create a virtual environment</p><pre>python3 -m venv myenv #change &#39;myenv&#39; to a different name</pre><h4>2. Enter venv</h4><pre>cd myenv</pre><pre>source bin/activate</pre><h4>3. Install packages</h4><pre>python -m pip install -U pip setuptools wheel</pre><pre>pip3 install torch torchvision torchaudio</pre><pre>pip install -U so-vits-svc-fork</pre><h4>4. Start the service</h4><pre>svcg</pre><ul><li><strong>Turn off “Use GPU.”</strong></li><li><strong>Click “infer” to start inference.</strong></li><li><strong>Try “F0 predict.”</strong></li><li><strong>The 4.1 model was not successfully tested here, so use webui.</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*sEyNSP8YOjEe0IYZ.png" /></figure><h3>SO-VITS-SVC 4.1 Inference</h3><p>Use the official repository’s WebUI: <a href="https://github.com/svc-develop-team/so-vits-svc">https://github.com/svc-develop-team/so-vits-svc</a></p><h4>1. Create venv</h4><p>Create a virtual environment</p><pre>python3.10 -m venv myenv #myvenv 自己换个名字好了,python3.9也是可以的</pre><h4>2. Enter venv</h4><pre>cd myenv</pre><pre>source bin/activate</pre><h4>3. Clone the repository</h4><pre>git clone https://github.com/svc-develop-team/so-vits-svc.git</pre><h4>4. Enter the directory</h4><pre>cd so-vits-svc</pre><h4>5. Install packages</h4><pre>pip install -r requirements.txt</pre><h4>6. Start WebUI</h4><p>(it’s normal if you can’t load models after entering WebUI)</p><pre>python webUI.py</pre><p>In case of WebUI related errors, limit dependency versions: fastapi==0.84.0, gradio==3.41.2, pydantic==1.10.12. Use the following commands to update the packages:</p><pre>pip install --upgrade fastapi==0.84.0</pre><pre>pip install --upgrade gradio==3.41.2</pre><pre>pip install --upgrade pydantic==1.10.12</pre><h4>7. Download some missing files</h4><p>(different files may be missing depending on the model)</p><p>The main missing files are in the pretrain folder. Add files according to the command line errors. You can download the necessary files from the cloud training server or download them from the provided links.</p><p>Configuration used currently:</p><pre><br># By default, use 768 with volume embedding<br>!python preprocess_flist_config.py --speech_encoder vec768l12 --vol_aug  <br>!rsync -v pre_trained_model/768l12/vol_emb/* logs/44k  <br># By default, use rmvpe with shallow diffusion<br>!python preprocess_hubert_f0.py --f0_predictor rmvpe --use_diff  <br>%cp pre_trained_model/diffusion/768l12/* logs/44k/diffusion  <br>##### Train shallow diffusion model<br>!python train_diff.py -c configs/diffusion.yaml   <br>##### Train main model<br>!python train.py -c configs/config.json -m 44k</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*47SJvEVMZ0-vLRKY.png" /></figure><p>The main missing files are in the pretrain folder. Follow the command line errors to add files.</p><p>Example of meta.py file structure:</p><pre>.  <br>├── checkpoint_best_legacy_500.pt  <br>├── chinese-hubert-large-fairseq-ckpt.pt  <br>├── fcpe.pt  <br>├── hubert-soft-0d54a1f4.pt  <br>├── __init__.py  <br>├── medium.pt  <br>├── meta.py  <br>├── nsf_hifigan  <br>│   ├── config.json  <br>│   ├── model  <br>│   ├── NOTICE.txt  <br>│   ├── NOTICE.zh-CN.txt  <br>│   └── put_nsf_hifigan_ckpt_here  <br>├── put_hubert_ckpt_here  <br>└── rmvpe.pt</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*9lZvizsFX1XnNKpC.png" /></figure><h3>Summary</h3><ul><li><strong>On Mac, there are still some issues with MPS, so it’s currently running on CPU. However, it’s at least working. Due to limited skills, this is the extent of the capability. Those with Windows and Nvidia cards will have a more comfortable experience.</strong></li><li><strong>Model: The training results are pretty good. You don’t need to train for a long time. A few hours on the server is enough (depending on the dataset). All datasets used for training were synthetic data generated from Elevenlab, of decent quality (for text inference). For TTS, Fish-Speech and Bert-Vits2 (good for Chinese) are recommended.</strong></li></ul><p>Thank you for reading. Please point out any issues or better methods in this tutorial.</p><p>Banner: [OPPO Reno 11 Pro Wallpaper](<a href="https://www.oppo.com/en/smartphones/series-reno/reno11-pro/specs/)**">https://www.oppo.com/en/smartphones/series-reno/reno11-pro/specs/)</a></p><p>Check out our source article for a better reading experience: <a href="https://blog.closex.org/posts/4208ff9d/">https://blog.closex.org/posts/4208ff9d/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b1ef804bb132" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>