atom.xml 300 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <feed xmlns="http://www.w3.org/2005/Atom">
  3. <title>Limour&#39;s Blog</title>
  4. <link href="https://hexo.limour.top/atom.xml" rel="self"/>
  5. <link href="https://hexo.limour.top/"/>
  6. <updated>2024-11-10T07:39:51.077Z</updated>
  7. <id>https://hexo.limour.top/</id>
  8. <author>
  9. <name>Limour</name>
  10. </author>
  11. <generator uri="https://hexo.io/">Hexo</generator>
  12. <entry>
  13. <title>【探索】使用 qdrant 进行向量检索</title>
  14. <link href="https://hexo.limour.top/using-qdrant-for-vector-retrieval"/>
  15. <id>https://hexo.limour.top/using-qdrant-for-vector-retrieval</id>
  16. <published>2024-11-10T04:43:15.000Z</published>
  17. <updated>2024-11-10T07:39:51.077Z</updated>
  18. <content type="html"><![CDATA[<p><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL3FkcmFudC9xZHJhbnQ=" rel="noopener external nofollow noreferrer">Qdrant</a> 是一个开源的向量数据库,专为高性能相似性搜索和机器学习应用而设计,比 <a href="./-qian-yi--ji-yu-Chroma-da-jian-ge-ren-zhi-shi-ku-de-quan-wen-suo-yin">Chroma</a> 更轻量(约80MiB)更快。它支持基于余弦相似度、欧氏距离等多种相似性度量的向量检索,并提供了灵活的过滤和分组功能。Qdrant 使用 Rust 语言编写,具有高效的索引和存储机制,能够快速处理大规模向量数据,适用于推荐系统、语义搜索、图像相似性匹配等场景。它提供了简单易用的 API,支持 gRPC 和 REST 接口,并且可以轻松集成到各种编程语言和机器学习框架中,是构建向量相似性搜索应用的理想选择。</p><h2 id="部署">部署</h2><ul><li><a href="/Docker-bu-shu-Nginx-Proxy-Manager">反向代理服务</a></li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">mkdir</span> -p ~/app/qdrant &amp;&amp; <span class="hljs-built_in">cd</span> ~/app/qdrant &amp;&amp; nano docker-compose.yml<br>wget https://raw.githubusercontent.com/qdrant/qdrant/refs/heads/master/config/production.yaml<br>sudo docker compose up -d<br>sudo docker compose logs<br></code></pre></td></tr></table></figure><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs yml"><span class="hljs-attr">services:</span><br> <span class="hljs-attr">qdrant:</span><br> <span class="hljs-attr">image:</span> <span class="hljs-string">qdrant/qdrant:latest</span><br> <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span><br> <span class="hljs-attr">expose:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-number">6333</span><br> <span class="hljs-bullet">-</span> <span class="hljs-number">6334</span><br> <span class="hljs-bullet">-</span> <span class="hljs-number">6335</span><br> <span class="hljs-attr">volumes:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">./qdrant_data:/qdrant/storage</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">./production.yaml:/qdrant/config/production.yaml</span><br> <br><span class="hljs-attr">networks:</span><br> <span class="hljs-attr">default:</span><br> <span class="hljs-attr">external:</span> <span class="hljs-literal">true</span><br> <span class="hljs-attr">name:</span> <span class="hljs-string">ngpm</span><br></code></pre></td></tr></table></figure><p><img src="https://img.limour.top/2024/11/10/673041358634e.webp" alt=""></p><ul><li>访问 <code>https://qdrant.limour.top/dashboard</code> 查看仪表盘</li></ul><h2 id="嵌入服务">嵌入服务</h2><ul><li>下载 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL2dnZXJnYW5vdi9sbGFtYS5jcHAvcmVsZWFzZXM=" rel="noopener external nofollow noreferrer">llama.cpp</a><ul><li>下载 <code>cudart-llama-bin-win-cu11.7.1-x64</code></li><li>下载对应后缀的 <code>llama-b4061-bin-win-cuda-cu11.7.1-x64</code></li><li>将两者解压到同一个目录</li></ul></li><li>从 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9zcGFjZXMvbXRlYi9sZWFkZXJib2FyZA==" rel="noopener external nofollow noreferrer">MTEB</a> 上找一个良好的嵌入模型</li><li>下载 GGUF 格式的嵌入模型,比如 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby93ZW5jYW4tbGFiL0RtZXRhLWVtYmVkZGluZy16aC1zbWFsbC1HR1VGL2Jsb2IvbWFpbi9EbWV0YS1lbWJlZGRpbmctemgtc21hbGwtUTRfS19NLmdndWY=" rel="noopener external nofollow noreferrer">Dmeta-embedding-zh-small-GGUF</a></li><li>根据<a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL2dnZXJnYW5vdi9sbGFtYS5jcHAvYmxvYi9tYXN0ZXIvZXhhbXBsZXMvc2VydmVyL1JFQURNRS5tZA==" rel="noopener external nofollow noreferrer">文档</a>配置参数启动嵌入服务</li></ul><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs powershell">./llama<span class="hljs-literal">-server</span>.exe <span class="hljs-literal">-m</span> ./embd/Dmeta<span class="hljs-literal">-embedding-zh-small-Q4_K_M</span>.gguf <span class="hljs-literal">-c</span> <span class="hljs-number">1024</span> <span class="hljs-literal">--embedding</span> <span class="hljs-literal">-fa</span> <span class="hljs-literal">-ngl</span> <span class="hljs-number">99</span><br></code></pre></td></tr></table></figure><ul><li>测试嵌入模型</li></ul><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs powershell"><span class="hljs-variable">$headers</span> = <span class="hljs-selector-tag">@</span>&#123;<br> <span class="hljs-string">&quot;Content-Type&quot;</span> = <span class="hljs-string">&quot;application/json&quot;</span><br> <span class="hljs-string">&quot;Authorization&quot;</span> = <span class="hljs-string">&quot;Bearer no-key&quot;</span><br>&#125;<br><br><span class="hljs-variable">$body</span> = <span class="hljs-selector-tag">@</span>&#123;<br> <span class="hljs-string">&quot;input&quot;</span> = <span class="hljs-selector-tag">@</span>(<span class="hljs-string">&quot;hello&quot;</span>, <span class="hljs-string">&quot;world&quot;</span>)<br> <span class="hljs-string">&quot;model&quot;</span> = <span class="hljs-string">&quot;GPT-4o&quot;</span><br> <span class="hljs-string">&quot;encoding_format&quot;</span> = <span class="hljs-string">&quot;float&quot;</span><br>&#125; | <span class="hljs-built_in">ConvertTo-Json</span><br><br><span class="hljs-variable">$response</span> = <span class="hljs-built_in">Invoke-WebRequest</span> <span class="hljs-literal">-Uri</span> <span class="hljs-string">&quot;http://localhost:8080/v1/embeddings&quot;</span> <span class="hljs-literal">-Method</span> Post <span class="hljs-literal">-Headers</span> <span class="hljs-variable">$headers</span> <span class="hljs-literal">-Body</span> <span class="hljs-variable">$body</span><br><br><span class="hljs-built_in">echo</span> <span class="hljs-variable">$response</span>.Content<br></code></pre></td></tr></table></figure><h2 id="客户端">客户端</h2><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs powershell">conda create <span class="hljs-literal">-n</span> rag conda<span class="hljs-literal">-forge</span>::qdrant<span class="hljs-literal">-client</span><br></code></pre></td></tr></table></figure><ul><li>获取测试所用内容 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvdGVzdF9yYWdfcWRyYW50" rel="noopener external nofollow noreferrer">test_rag_qdrant</a></li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> os<br><span class="hljs-keyword">from</span> qdrant_client <span class="hljs-keyword">import</span> QdrantClient<br><span class="hljs-keyword">from</span> qdrant_client.models <span class="hljs-keyword">import</span> VectorParams, Distance<br><span class="hljs-keyword">from</span> qdrant_client.models <span class="hljs-keyword">import</span> PointStruct<br><span class="hljs-keyword">from</span> m98_rag <span class="hljs-keyword">import</span> embd, readChunks<br><br>QDRANT_URL = os.getenv(<span class="hljs-string">&#x27;QDRANT_URL&#x27;</span>, <span class="hljs-string">&#x27;http://localhost:6333&#x27;</span>)<br>QDRANT_KEY = os.getenv(<span class="hljs-string">&#x27;QDRANT_KEY&#x27;</span>, <span class="hljs-string">&#x27;&#x27;</span>)<br><br>client = QdrantClient(url=QDRANT_URL,<br> api_key=QDRANT_KEY,<br> timeout=<span class="hljs-number">100</span>)<br><br><span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> client.collection_exists(<span class="hljs-string">&quot;my_collection&quot;</span>):<br> client.create_collection(<br> collection_name=<span class="hljs-string">&quot;my_collection&quot;</span>,<br> vectors_config=VectorParams(size=<span class="hljs-number">768</span>, distance=Distance.COSINE)<br> )<br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&#x27;__main__&#x27;</span>:<br> <span class="hljs-built_in">print</span>(QDRANT_URL)<br> <span class="hljs-built_in">print</span>(QDRANT_KEY)<br> chunks = readChunks(<span class="hljs-string">&#x27;./test.md&#x27;</span>)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, <span class="hljs-built_in">len</span>(chunks), <span class="hljs-number">8</span>):<br> batch = chunks[i: i+<span class="hljs-number">8</span>]<br> <span class="hljs-built_in">print</span>(batch)<br> vectors = embd(batch)<br> client.upsert(<br> collection_name=<span class="hljs-string">&quot;my_collection&quot;</span>,<br> points=[<br> PointStruct(<br> <span class="hljs-built_in">id</span>=i+idx,<br> vector=vector[<span class="hljs-number">1</span>],<br> payload=&#123;<span class="hljs-string">&quot;text&quot;</span>: vector[<span class="hljs-number">0</span>]&#125;<br> )<br> <span class="hljs-keyword">for</span> idx, vector <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(vectors)<br> ]<br> )<br> <span class="hljs-comment"># 进行搜索</span><br> query_vector = embd([<span class="hljs-string">&#x27;机器人限拥令是什么?&#x27;</span>])<br> hits = client.search(<br> collection_name=<span class="hljs-string">&quot;my_collection&quot;</span>,<br> query_vector=query_vector[<span class="hljs-number">0</span>][<span class="hljs-number">1</span>],<br> limit=<span class="hljs-number">5</span> <span class="hljs-comment"># Return 5 closest points</span><br> )<br> <span class="hljs-built_in">print</span>(hits[<span class="hljs-number">0</span>].payload[<span class="hljs-string">&#x27;text&#x27;</span>])<br></code></pre></td></tr></table></figure><ul><li>所得到的结果还不错~</li></ul><figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs txt">24小时客服在线电话:1919-114514810 <br> *注意:根据《国家质量标准认证iso7002》,《机器人管理条例》,机器人类产品不宜连续使用超过十五年。请定期到指定售后地点进行重置。 <br>## 十三<br>机器人限拥令的实施开端于2090年5月的一起案件。<br>被害人约翰逊的尸体在其失踪的次日被发现于他自家的住宅。死状相当惨烈:在R级新闻团体才能合法展示的照片中,整个人被从身体中间沿着脊椎切割成两半,一半被他所购买的机器人ct13694582(型号为玛格丽特c6)紧紧抱在床上,另一半被他购买的另一台机器人ct12487967(型号为子矜7z)小心的存放在冷库里。案件现场几乎满地都是受害人的血,散发着浓烈的腥味,而身为罪魁祸首的两台机器人,一台已经关机,另一台则刻板地重复着几个动作。<br>根据记录,两台机器人和受害人共处的时间分别长达18年和17年。在这么长的时间里,受害人以近乎均等的时间使用二者,并不下数百次的分别向它们倾诉 我最爱的是你 我只爱你一个人 你比她漂亮多了 等明显带有示爱情绪的情话。<br></code></pre></td></tr></table></figure>]]></content>
  19. <summary type="html">&lt;p&gt;&lt;a href=&quot;https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL3FkcmFudC9xZHJhbnQ=&quot; rel=&quot;noopener external nofollow noreferrer&quot;&gt;Qdrant&lt;/a&gt;</summary>
  20. <category term="docker" scheme="https://hexo.limour.top/tags/docker/"/>
  21. <category term="rag" scheme="https://hexo.limour.top/tags/rag/"/>
  22. </entry>
  23. <entry>
  24. <title>【记录】使用 circacompare 分析生物节律</title>
  25. <link href="https://hexo.limour.top/shi-yong-circacompare-fen-xi-sheng-wu-jie-lv"/>
  26. <id>https://hexo.limour.top/shi-yong-circacompare-fen-xi-sheng-wu-jie-lv</id>
  27. <published>2024-11-08T15:50:20.000Z</published>
  28. <updated>2024-11-08T16:38:08.915Z</updated>
  29. <content type="html"><![CDATA[<p>circacompare 是一个专为分析生物节律数据而设计的 R 包。它的主要功能是比较不同条件下的节律参数,例如振幅、周期和相位。circacompare 使用非线性混合效应模型来拟合节律数据,这使得它在处理具有重复测量和复杂实验设计的数据时表现出色。与 circacompare 相比,<a href="./shi-yong--JTK-CYCLE--suan-fa-fen-xi-sheng-wu-jie-lv">MetaCycle</a> 是另一个流行的 R 包,用于生物节律分析。MetaCycle 提供了多种算法(如 ARSER、JTK_CYCLE 和 Lomb-Scargle)来检测时间序列数据中的周期性信号。它的优势在于能够处理大规模数据集,并且适用于各种不同的实验条件。</p><h2 id="conda安装包">conda安装包</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash">conda create -n zct conda-forge::r-tidyverse conda-forge::r-irkernel<br>conda run -n zct Rscript -e <span class="hljs-string">&quot;IRkernel::installspec(name=&#x27;zct&#x27;, displayname=&#x27;zct&#x27;)&quot;</span><br>conda run -n zct Rscript -e <span class="hljs-string">&quot;install.packages(&#x27;circacompare&#x27;)&quot;</span><br></code></pre></td></tr></table></figure><h2 id="导入包和数据">导入包和数据</h2><figure class="highlight r"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs R">library<span class="hljs-punctuation">(</span>tidyverse<span class="hljs-punctuation">)</span><br>library<span class="hljs-punctuation">(</span>circacompare<span class="hljs-punctuation">)</span><br>library<span class="hljs-punctuation">(</span>ggplot2<span class="hljs-punctuation">)</span><br><br>dt <span class="hljs-operator">&lt;-</span> readr<span class="hljs-operator">::</span>read_csv<span class="hljs-punctuation">(</span><span class="hljs-string">&#x27;./circacompare.CSV&#x27;</span><span class="hljs-punctuation">)</span> <span class="hljs-operator">%&gt;%</span> <br>mutate<span class="hljs-punctuation">(</span>group <span class="hljs-operator">=</span> factor<span class="hljs-punctuation">(</span>group<span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span> <span class="hljs-operator">%&gt;%</span> <br>mutate<span class="hljs-punctuation">(</span>organ <span class="hljs-operator">=</span> factor<span class="hljs-punctuation">(</span>organ<span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span> <span class="hljs-operator">%&gt;%</span> <br>mutate<span class="hljs-punctuation">(</span>project <span class="hljs-operator">=</span> factor<span class="hljs-punctuation">(</span>project<span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><br></code></pre></td></tr></table></figure><h2 id="两组比较">两组比较</h2><figure class="highlight r"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs R">s_symbol <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;Bmal1&#x27;</span> <br>s_organ <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;Heart&#x27;</span><br>s_project <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;compare1&#x27;</span><br><br><span class="hljs-comment"># 根据参数选择数据</span><br>dt_s <span class="hljs-operator">&lt;-</span> dt <span class="hljs-operator">%&gt;%</span> <br>subset<span class="hljs-punctuation">(</span>symbol <span class="hljs-operator">==</span> s_symbol <span class="hljs-operator">&amp;</span> organ <span class="hljs-operator">==</span> s_organ <span class="hljs-operator">&amp;</span> project <span class="hljs-operator">==</span> s_project<span class="hljs-punctuation">)</span> <span class="hljs-operator">%&gt;%</span> <br>mutate<span class="hljs-punctuation">(</span>group <span class="hljs-operator">=</span> factor<span class="hljs-punctuation">(</span>group<span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><br><span class="hljs-comment"># 进行比较</span><br>result <span class="hljs-operator">&lt;-</span> circacompare<span class="hljs-punctuation">(</span>x <span class="hljs-operator">=</span> dt_s<span class="hljs-punctuation">,</span> col_time <span class="hljs-operator">=</span> <span class="hljs-string">&quot;time&quot;</span><span class="hljs-punctuation">,</span> col_group <span class="hljs-operator">=</span> <span class="hljs-string">&quot;group&quot;</span><span class="hljs-punctuation">,</span> col_outcome <span class="hljs-operator">=</span> <span class="hljs-string">&quot;measure&quot;</span><span class="hljs-punctuation">,</span> alpha_threshold <span class="hljs-operator">=</span> <span class="hljs-number">1</span><span class="hljs-punctuation">)</span><br><span class="hljs-comment"># 查看统计汇总</span><br>result<span class="hljs-operator">$</span>summary<br>circacompare<span class="hljs-operator">:::</span>extract_model_coefs<span class="hljs-punctuation">(</span>result<span class="hljs-operator">$</span>fit<span class="hljs-punctuation">)</span><br><br><span class="hljs-comment"># 查看绘图</span><br>save_plot <span class="hljs-operator">&lt;-</span> result<span class="hljs-operator">$</span>plot <span class="hljs-operator">+</span> <br>theme_minimal<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span> <span class="hljs-operator">+</span> <br>ggtitle<span class="hljs-punctuation">(</span>paste<span class="hljs-punctuation">(</span><span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span>s_symbol<span class="hljs-punctuation">,</span> s_organ<span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> collapse <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;_&#x27;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span> <span class="hljs-operator">+</span><br>theme<span class="hljs-punctuation">(</span>plot.title <span class="hljs-operator">=</span> element_text<span class="hljs-punctuation">(</span>hjust <span class="hljs-operator">=</span> <span class="hljs-number">0.5</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><br><br>save_plot<br><br><span class="hljs-comment"># 保存图为 pdf</span><br><span class="hljs-punctuation">&#123;</span>pdf<span class="hljs-punctuation">(</span>file <span class="hljs-operator">=</span> paste0<span class="hljs-punctuation">(</span><span class="hljs-string">&#x27;pdf/&#x27;</span><span class="hljs-punctuation">,</span> paste<span class="hljs-punctuation">(</span><span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span>s_symbol<span class="hljs-punctuation">,</span> s_organ<span class="hljs-punctuation">,</span> s_project<span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> collapse <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;_&#x27;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&#x27;.pdf&#x27;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> width <span class="hljs-operator">=</span> <span class="hljs-number">6</span><span class="hljs-punctuation">,</span> height <span class="hljs-operator">=</span> <span class="hljs-number">6</span><span class="hljs-punctuation">)</span><br> print<span class="hljs-punctuation">(</span>save_plot<span class="hljs-punctuation">)</span><br>dev.off<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><h2 id="单组绘图">单组绘图</h2><figure class="highlight r"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs R">s_symbol <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;Rev-erbα&#x27;</span> <br>s_organ <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;Kidney&#x27;</span><br>s_project <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;KO-AL&#x27;</span><br><br><span class="hljs-comment"># 根据参数选择数据</span><br>dt_s <span class="hljs-operator">&lt;-</span> dt <span class="hljs-operator">%&gt;%</span> <br>subset<span class="hljs-punctuation">(</span>symbol <span class="hljs-operator">==</span> s_symbol <span class="hljs-operator">&amp;</span> organ <span class="hljs-operator">==</span> s_organ <span class="hljs-operator">&amp;</span> project <span class="hljs-operator">==</span> s_project<span class="hljs-punctuation">)</span> <span class="hljs-operator">%&gt;%</span> <br>mutate<span class="hljs-punctuation">(</span>group <span class="hljs-operator">=</span> factor<span class="hljs-punctuation">(</span>group<span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><br><br><span class="hljs-comment"># 进行统计分析</span><br>options<span class="hljs-punctuation">(</span>show.error.messages <span class="hljs-operator">=</span> <span class="hljs-built_in">F</span><span class="hljs-punctuation">,</span> warn <span class="hljs-operator">=</span> <span class="hljs-operator">-</span><span class="hljs-number">1</span><span class="hljs-punctuation">)</span><br>result <span class="hljs-operator">&lt;-</span> try<span class="hljs-punctuation">(</span><span class="hljs-punctuation">&#123;</span><br> circa_single<span class="hljs-punctuation">(</span><br> x <span class="hljs-operator">=</span> dt_s<span class="hljs-punctuation">,</span> col_time <span class="hljs-operator">=</span> <span class="hljs-string">&quot;time&quot;</span><span class="hljs-punctuation">,</span> col_outcome <span class="hljs-operator">=</span> <span class="hljs-string">&quot;measure&quot;</span><span class="hljs-punctuation">,</span> period <span class="hljs-operator">=</span> <span class="hljs-number">24</span><span class="hljs-punctuation">,</span> alpha_threshold <span class="hljs-operator">=</span> <span class="hljs-number">1</span><span class="hljs-punctuation">,</span><br> timeout_n <span class="hljs-operator">=</span> <span class="hljs-number">100000</span><span class="hljs-punctuation">,</span><br> control <span class="hljs-operator">=</span> <span class="hljs-built_in">list</span><span class="hljs-punctuation">(</span><br> main_params <span class="hljs-operator">=</span> <span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span><span class="hljs-string">&quot;k&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;alpha&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;phi&quot;</span><span class="hljs-punctuation">)</span><br> <span class="hljs-punctuation">)</span><br> <span class="hljs-punctuation">)</span><br><span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span> silent <span class="hljs-operator">=</span> <span class="hljs-literal">TRUE</span><span class="hljs-punctuation">)</span><br>options<span class="hljs-punctuation">(</span>show.error.messages <span class="hljs-operator">=</span> <span class="hljs-built_in">T</span><span class="hljs-punctuation">,</span> warn <span class="hljs-operator">=</span> <span class="hljs-number">1</span><span class="hljs-punctuation">)</span><br><span class="hljs-comment"># “k”表示中值,“alpha”表示振幅,“phi”表示相位。引入的额外参数是“tau”表示周期。</span><br><br><br><span class="hljs-comment"># 查看统计汇总</span><br>result<span class="hljs-operator">$</span>summary<br>circacompare<span class="hljs-operator">:::</span>extract_model_coefs<span class="hljs-punctuation">(</span>result<span class="hljs-operator">$</span>fit<span class="hljs-punctuation">)</span><br><br><span class="hljs-comment"># 查看绘图</span><br>save_plot <span class="hljs-operator">&lt;-</span> result<span class="hljs-operator">$</span>plot <span class="hljs-operator">+</span> <br>theme_minimal<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span> <span class="hljs-operator">+</span> <br>ggtitle<span class="hljs-punctuation">(</span>paste<span class="hljs-punctuation">(</span><span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span>s_symbol<span class="hljs-punctuation">,</span> s_organ<span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> collapse <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;_&#x27;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span> <span class="hljs-operator">+</span><br>theme<span class="hljs-punctuation">(</span>plot.title <span class="hljs-operator">=</span> element_text<span class="hljs-punctuation">(</span>hjust <span class="hljs-operator">=</span> <span class="hljs-number">0.5</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><br><br>save_plot<br><br><span class="hljs-comment"># 保存图为 pdf</span><br><span class="hljs-punctuation">&#123;</span>pdf<span class="hljs-punctuation">(</span>file <span class="hljs-operator">=</span> paste0<span class="hljs-punctuation">(</span><span class="hljs-string">&#x27;pdf/&#x27;</span><span class="hljs-punctuation">,</span> paste<span class="hljs-punctuation">(</span><span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span>s_symbol<span class="hljs-punctuation">,</span> s_organ<span class="hljs-punctuation">,</span> s_project<span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> collapse <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;_&#x27;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&#x27;.pdf&#x27;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> width <span class="hljs-operator">=</span> <span class="hljs-number">6</span><span class="hljs-punctuation">,</span> height <span class="hljs-operator">=</span> <span class="hljs-number">6</span><span class="hljs-punctuation">)</span><br> print<span class="hljs-punctuation">(</span>save_plot<span class="hljs-punctuation">)</span><br>dev.off<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><h2 id="周期和衰减参数">周期和衰减参数</h2><figure class="highlight r"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs R">s_symbol <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;Bmal1&#x27;</span> <br>s_organ <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;Heart&#x27;</span><br>s_project <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;compare1&#x27;</span><br><br><span class="hljs-comment"># 根据参数选择数据</span><br>dt_s <span class="hljs-operator">&lt;-</span> dt <span class="hljs-operator">%&gt;%</span> <br>subset<span class="hljs-punctuation">(</span>symbol <span class="hljs-operator">==</span> s_symbol <span class="hljs-operator">&amp;</span> organ <span class="hljs-operator">==</span> s_organ <span class="hljs-operator">&amp;</span> project <span class="hljs-operator">==</span> s_project<span class="hljs-punctuation">)</span> <span class="hljs-operator">%&gt;%</span> <br>mutate<span class="hljs-punctuation">(</span>group <span class="hljs-operator">=</span> factor<span class="hljs-punctuation">(</span>group<span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><br><br><span class="hljs-comment"># 进行统计分析</span><br>options<span class="hljs-punctuation">(</span>show.error.messages <span class="hljs-operator">=</span> <span class="hljs-built_in">F</span><span class="hljs-punctuation">,</span> warn <span class="hljs-operator">=</span> <span class="hljs-operator">-</span><span class="hljs-number">1</span><span class="hljs-punctuation">)</span><br>result <span class="hljs-operator">&lt;-</span> try<span class="hljs-punctuation">(</span><span class="hljs-punctuation">&#123;</span><br> circacompare<span class="hljs-punctuation">(</span><br> x <span class="hljs-operator">=</span> dt_s<span class="hljs-punctuation">,</span> col_time <span class="hljs-operator">=</span> <span class="hljs-string">&quot;time&quot;</span><span class="hljs-punctuation">,</span> col_group <span class="hljs-operator">=</span> <span class="hljs-string">&quot;group&quot;</span><span class="hljs-punctuation">,</span> col_outcome <span class="hljs-operator">=</span> <span class="hljs-string">&quot;measure&quot;</span><span class="hljs-punctuation">,</span> period <span class="hljs-operator">=</span> <span class="hljs-number">24</span><span class="hljs-punctuation">,</span> alpha_threshold <span class="hljs-operator">=</span> <span class="hljs-number">1</span><span class="hljs-punctuation">,</span><br> timeout_n <span class="hljs-operator">=</span> <span class="hljs-number">100000</span><span class="hljs-punctuation">,</span><br> control <span class="hljs-operator">=</span> <span class="hljs-built_in">list</span><span class="hljs-punctuation">(</span><br> main_params <span class="hljs-operator">=</span> <span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span><span class="hljs-string">&quot;k&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;alpha&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;phi&quot;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span><br> decay_params <span class="hljs-operator">=</span> <span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span><span class="hljs-string">&quot;alpha&quot;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span><br> grouped_params <span class="hljs-operator">=</span> <span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span><span class="hljs-string">&quot;alpha&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;alpha_decay&quot;</span><span class="hljs-punctuation">)</span><br> <span class="hljs-punctuation">)</span><br> <span class="hljs-punctuation">)</span><br><span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span> silent <span class="hljs-operator">=</span> <span class="hljs-literal">TRUE</span><span class="hljs-punctuation">)</span><br>options<span class="hljs-punctuation">(</span>show.error.messages <span class="hljs-operator">=</span> <span class="hljs-built_in">T</span><span class="hljs-punctuation">,</span> warn <span class="hljs-operator">=</span> <span class="hljs-number">1</span><span class="hljs-punctuation">)</span><br><span class="hljs-comment"># “k”表示中值,“alpha”表示振幅,“phi”表示相位。引入的额外参数是“tau”表示周期。</span><br><br><span class="hljs-comment"># 查看统计汇总</span><br>result<span class="hljs-operator">$</span>summary<br>circacompare<span class="hljs-operator">:::</span>extract_model_coefs<span class="hljs-punctuation">(</span>result<span class="hljs-operator">$</span>fit<span class="hljs-punctuation">)</span><br><br><span class="hljs-comment"># 查看绘图</span><br>save_plot <span class="hljs-operator">&lt;-</span> result<span class="hljs-operator">$</span>plot <span class="hljs-operator">+</span> <br>theme_minimal<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span> <span class="hljs-operator">+</span> <br>ggtitle<span class="hljs-punctuation">(</span>paste<span class="hljs-punctuation">(</span><span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span>s_symbol<span class="hljs-punctuation">,</span> s_organ<span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> collapse <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;_&#x27;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span> <span class="hljs-operator">+</span><br>theme<span class="hljs-punctuation">(</span>plot.title <span class="hljs-operator">=</span> element_text<span class="hljs-punctuation">(</span>hjust <span class="hljs-operator">=</span> <span class="hljs-number">0.5</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><br><br>save_plot<br><br><span class="hljs-comment"># 保存图为 pdf</span><br><span class="hljs-punctuation">&#123;</span>pdf<span class="hljs-punctuation">(</span>file <span class="hljs-operator">=</span> paste0<span class="hljs-punctuation">(</span><span class="hljs-string">&#x27;pdf/&#x27;</span><span class="hljs-punctuation">,</span> paste<span class="hljs-punctuation">(</span><span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span>s_symbol<span class="hljs-punctuation">,</span> s_organ<span class="hljs-punctuation">,</span> s_project<span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> collapse <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;_&#x27;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&#x27;_decay.pdf&#x27;</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> width <span class="hljs-operator">=</span> <span class="hljs-number">6</span><span class="hljs-punctuation">,</span> height <span class="hljs-operator">=</span> <span class="hljs-number">6</span><span class="hljs-punctuation">)</span><br> print<span class="hljs-punctuation">(</span>save_plot<span class="hljs-punctuation">)</span><br>dev.off<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure>]]></content>
  30. <summary type="html">&lt;p&gt;circacompare 是一个专为分析生物节律数据而设计的 R 包。它的主要功能是比较不同条件下的节律参数,例如振幅、周期和相位。circacompare 使用非线性混合效应模型来拟合节律数据,这使得它在处理具有重复测量和复杂实验设计的数据时表现出色。与 circacom</summary>
  31. <category term="节律" scheme="https://hexo.limour.top/tags/%E8%8A%82%E5%BE%8B/"/>
  32. </entry>
  33. <entry>
  34. <title>【记录】将OSS挂载为WebDAV</title>
  35. <link href="https://hexo.limour.top/Mount-OSS-as-a-WebMAV"/>
  36. <id>https://hexo.limour.top/Mount-OSS-as-a-WebMAV</id>
  37. <published>2024-11-01T05:03:45.000Z</published>
  38. <updated>2024-11-01T05:18:41.754Z</updated>
  39. <content type="html"><![CDATA[<p>OSS(对象存储服务)是一种分布式存储服务,它提供了简单的Web服务接口,使得用户可以在任何地方、任何时间存储和检索数据。而WebDAV(基于Web的分布式创作和版本控制)则是一个基于HTTP的协议,它允许用户通过网络对文件进行编辑和管理。将OSS转换成WebDAV可以方便使用Zotero这类文献管理软件进行同步。Zotero支持通过WebDAV协议同步附件,这样用户可以在不同的设备和平台上访问和管理自己的文献资料,提高了工作和研究的效率。因此,使用WebDAV对接OSS可以为Zotero用户带来极大的便利。</p><h2 id="新建-OSS-桶">新建 OSS 桶</h2><ul><li>新建一个储存桶,记录下<code>桶名称</code></li><li>新建一个RAM角色</li><li>记录下 <code>AccessKey ID</code> 和 <code>AccessKey Secret</code></li></ul><p><img src="https://img.limour.top/2024/11/01/6724624067144.webp" alt=""><br><img src="https://img.limour.top/2024/11/01/672462819133e.webp" alt=""></p><ul><li>授予访问权限,用 <code>http</code> 而非 <code>https</code>,因为 <code>ossfs-webdav</code> 很老了</li></ul><p><img src="https://img.limour.top/2024/11/01/672462bd10e86.webp" alt=""></p><ul><li>记录下<code>内网 EndPoint</code></li></ul><p><img src="https://img.limour.top/2024/11/01/6724631500a13.webp" alt=""></p><h2 id="转-WebDAV">转 WebDAV</h2><ul><li><a href="/Docker-bu-shu-Nginx-Proxy-Manager">反向代理服务</a></li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">mkdir</span> -p ~/app/ossfs &amp;&amp; <span class="hljs-built_in">cd</span> ~/app/ossfs &amp;&amp; nano docker-compose.yml<br>sudo docker compose up -d<br></code></pre></td></tr></table></figure><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs yml"><span class="hljs-attr">version:</span> <span class="hljs-string">&quot;3&quot;</span><br><span class="hljs-attr">services:</span><br> <span class="hljs-attr">ossfs:</span><br> <span class="hljs-attr">image:</span> <span class="hljs-string">xxx.limour.top/yindaheng98/ossfs-webdav</span><br> <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span><br> <span class="hljs-attr">cap_add:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">SYS_ADMIN</span><br> <span class="hljs-attr">devices:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">/dev/fuse</span><br> <span class="hljs-attr">security_opt:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">apparmor=unconfined</span><br> <span class="hljs-attr">environment:</span><br> <span class="hljs-attr">SERVER_NAMES:</span> <span class="hljs-string">zotero.limour.top</span><br> <span class="hljs-attr">BucketName:</span> <span class="hljs-string">你的BucketName</span><br> <span class="hljs-attr">AccessKeyId:</span> <span class="hljs-string">你的AccessKeyId</span><br> <span class="hljs-attr">AccessKeySecret:</span> <span class="hljs-string">你的AccessKeySecret</span><br> <span class="hljs-attr">EndPoint:</span> <span class="hljs-string">你的EndPoint</span><br> <span class="hljs-attr">USERNAME:</span> <span class="hljs-string">你的webdav用户名</span><br> <span class="hljs-attr">PASSWORD:</span> <span class="hljs-string">你的webdav密码</span><br> <span class="hljs-attr">OWNER_USER:</span> <span class="hljs-string">www-data</span><br> <span class="hljs-attr">OWNER_GROUP:</span> <span class="hljs-string">www-data</span><br> <br><span class="hljs-attr">networks:</span><br> <span class="hljs-attr">default:</span><br> <span class="hljs-attr">external:</span> <span class="hljs-literal">true</span><br> <span class="hljs-attr">name:</span> <span class="hljs-string">ngpm</span><br></code></pre></td></tr></table></figure><h2 id="配置反代">配置反代</h2><p><img src="https://img.limour.top/2024/11/01/672463b1b0c91.webp" alt=""></p>]]></content>
  40. <summary type="html">&lt;p&gt;OSS(对象存储服务)是一种分布式存储服务,它提供了简单的Web服务接口,使得用户可以在任何地方、任何时间存储和检索数据。而WebDAV(基于Web的分布式创作和版本控制)则是一个基于HTTP的协议,它允许用户通过网络对文件进行编辑和管理。将OSS转换成WebDAV可以方便</summary>
  41. <category term="oss" scheme="https://hexo.limour.top/tags/oss/"/>
  42. </entry>
  43. <entry>
  44. <title>【记录】内网使用P4wnP1传递文件</title>
  45. <link href="https://hexo.limour.top/internal-network-uses-p4wnp1-to-transfer-file"/>
  46. <id>https://hexo.limour.top/internal-network-uses-p4wnp1-to-transfer-file</id>
  47. <published>2024-10-27T07:05:01.000Z</published>
  48. <updated>2024-10-29T13:42:04.082Z</updated>
  49. <content type="html"><![CDATA[<p>最近实习轮转到预防了,需要在社区实习4周,而社区医生有一堆需要重复填报的数据,因此写了下面的脚本来自动化填写。而问题是社区的电脑禁用了U盘等设备的使用,因此想将这个脚本传递到其他电脑上只能手打一次。。。<br>于是想到的吃灰已久的<code>树莓派zero w</code>,给它刷上了 <code>P4wnP1 ALOA</code> 来模拟键盘输入,这样就不用手打了。</p> <div class="fold"> <div class="fold-title fold-info collapsed" data-toggle="collapse" href="#collapse-8f7bdefe" role="button" aria-expanded="false" aria-controls="collapse-8f7bdefe"> <div class="fold-arrow">▶</div>点开查看社区填报自动化脚本 </div> <div class="fold-collapse collapse" id="collapse-8f7bdefe"> <div class="fold-content"> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-params">timeout</span>) &#123;<br> <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>)=&gt;</span>&#123;<br> <span class="hljs-built_in">setTimeout</span>(resolve, timeout * <span class="hljs-number">1000</span>);<br> &#125;<br> );<br>&#125;<br>;<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">processRows</span>(<span class="hljs-params"></span>) &#123;<br><br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt;= <span class="hljs-number">29</span>; i++) &#123;<br><br> <span class="hljs-keyword">var</span> orignialWindowOpen = <span class="hljs-variable language_">window</span>.<span class="hljs-property">open</span>;<br> <span class="hljs-variable language_">window</span>.<span class="hljs-property">open</span> = <span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) &#123;<br> <span class="hljs-keyword">var</span> taskid = i + <span class="hljs-number">1</span><br> <span class="hljs-keyword">var</span> newWindow = orignialWindowOpen.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">1</span>);<br> <span class="hljs-comment">// var newWindow = window; //调试用</span><br> <span class="hljs-comment">// console.log(&quot;newWindow &quot;, newWindow);</span><br> <span class="hljs-comment">// 100s 强制关闭</span><br> <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">()=&gt;</span>&#123;<br> <span class="hljs-keyword">if</span> (!newWindow.<span class="hljs-property">closed</span>) &#123;<br> newWindow.<span class="hljs-title function_">close</span>();<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;Manipulating Row&quot;</span>, taskid, <span class="hljs-string">&quot;Window closed at 100s&quot;</span>);<br> &#125;<br> &#125;<br> , <span class="hljs-number">100000</span>);<br><br> <span class="hljs-keyword">var</span> alerted = <span class="hljs-literal">false</span>;<br> newWindow.<span class="hljs-property">confirm</span> = <span class="hljs-function">(<span class="hljs-params">m</span>)=&gt;</span><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;confirm&#x27;</span>, taskid, m);<br> newWindow.<span class="hljs-property">alert</span> = <span class="hljs-function">(<span class="hljs-params">m</span>)=&gt;</span>&#123;<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;alert&#x27;</span>, taskid, m);<br> alerted = <span class="hljs-literal">true</span>;<br> &#125;<br><br> <span class="hljs-keyword">var</span> <span class="hljs-title function_">isElLoaded</span> = <span class="hljs-keyword">async</span> sl=&gt;&#123;<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">0.05</span>);<br> <span class="hljs-keyword">if</span> (newWindow.<span class="hljs-property">closed</span>) &#123;<br> <span class="hljs-keyword">throw</span> taskid + <span class="hljs-string">&quot;newWindow.closed&quot;</span><br> &#125;<br> <span class="hljs-keyword">while</span> (newWindow.<span class="hljs-property">document</span>.<span class="hljs-title function_">querySelector</span>(sl) === <span class="hljs-literal">null</span>) &#123;<br> <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>)=&gt;</span>&#123;<br> <span class="hljs-title function_">requestAnimationFrame</span>(resolve)<br> &#125;<br> );<br> &#125;<br> ;<span class="hljs-keyword">return</span> newWindow.<span class="hljs-property">document</span>.<span class="hljs-title function_">querySelector</span>(sl);<br> &#125;<br> ;<br> <span class="hljs-keyword">function</span> <span class="hljs-title function_">rrrand</span>(<span class="hljs-params">min, max</span>) &#123;<br> <span class="hljs-keyword">return</span> <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">floor</span>(<span class="hljs-title class_">Math</span>.<span class="hljs-title function_">random</span>() * (max - min + <span class="hljs-number">1</span>)) + min<br> &#125;<br> ;<span class="hljs-keyword">function</span> <span class="hljs-title function_">setValue</span>(<span class="hljs-params">el, min, max</span>) &#123;<br> <span class="hljs-keyword">if</span> (!el || !el.<span class="hljs-property">value</span>) &#123;<br> el.<span class="hljs-property">value</span> = <span class="hljs-title function_">rrrand</span>(min, max).<span class="hljs-title function_">toFixed</span>(<span class="hljs-number">1</span>);<br> &#125;<br> &#125;<br> ;<span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">0.5</span>);<br><br> taskid = (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#Name&quot;</span>)).<span class="hljs-property">value</span> + <span class="hljs-string">&#x27; &#x27;</span> + taskid;<br><br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset1 &gt; fieldset &gt; div &gt; div &gt; label:nth-child(1) &gt; input&quot;</span>)).<span class="hljs-property">checked</span> = <span class="hljs-literal">true</span>;<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset15 &gt; fieldset &gt; div &gt; div &gt; label:nth-child(1) &gt; input&quot;</span>)).<span class="hljs-property">checked</span> = <span class="hljs-literal">true</span>;<br><br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset3 &gt; fieldset &gt; legend &gt; span.title_icon.plus_icon&quot;</span>)).<span class="hljs-title function_">click</span>();<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">1</span>);<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset3 &gt; fieldset &gt; div:nth-child(2) &gt; div:nth-child(2) &gt; div &gt; label:nth-child(4) &gt; input[type=radio]&quot;</span>)).<span class="hljs-title function_">click</span>();<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">0.3</span>);<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset3 &gt; fieldset &gt; div:nth-child(3) &gt; div &gt; label:nth-child(1) &gt; input[type=radio]&quot;</span>)).<span class="hljs-title function_">click</span>();<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">0.3</span>);<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset3 &gt; fieldset &gt; div:nth-child(4) &gt; div:nth-child(2) &gt; div &gt; label:nth-child(1) &gt; input[type=radio]&quot;</span>)).<span class="hljs-title function_">click</span>();<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">0.3</span>);<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#yjqk&quot;</span>)).<span class="hljs-title function_">click</span>();<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">0.3</span>);<br><br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset4 &gt; fieldset &gt; div:nth-child(2) &gt; div &gt; label:nth-child(1) &gt; input&quot;</span>)).<span class="hljs-property">checked</span> = <span class="hljs-literal">true</span>;<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset4 &gt; fieldset &gt; div:nth-child(3) &gt; div &gt; label:nth-child(1) &gt; input&quot;</span>)).<span class="hljs-property">checked</span> = <span class="hljs-literal">true</span>;<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset4 &gt; fieldset &gt; div:nth-child(4) &gt; div &gt; label:nth-child(1) &gt; input&quot;</span>)).<span class="hljs-property">checked</span> = <span class="hljs-literal">true</span>;<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset4 &gt; fieldset &gt; div:nth-child(5) &gt; div &gt; label:nth-child(1) &gt; input&quot;</span>)).<span class="hljs-property">checked</span> = <span class="hljs-literal">true</span>;<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset4 &gt; fieldset &gt; div:nth-child(6) &gt; div &gt; label:nth-child(1) &gt; input&quot;</span>)).<span class="hljs-property">checked</span> = <span class="hljs-literal">true</span>;<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset4 &gt; fieldset &gt; div:nth-child(7) &gt; div &gt; label:nth-child(1) &gt; input&quot;</span>)).<span class="hljs-property">checked</span> = <span class="hljs-literal">true</span>;<br><br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset4 &gt; fieldset &gt; div:nth-child(8) &gt; div &gt; label:nth-child(1) &gt; input[type=radio]&quot;</span>)).<span class="hljs-title function_">click</span>();<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">0.3</span>);<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#d1 &gt; div.fieldset4 &gt; fieldset &gt; div:nth-child(9) &gt; div &gt; label:nth-child(1) &gt; input[type=radio]&quot;</span>)).<span class="hljs-title function_">click</span>();<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">0.3</span>);<br><br> <span class="hljs-keyword">var</span> sg = <span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#sg&quot;</span>);<br> <span class="hljs-keyword">var</span> tz = <span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#tz&quot;</span>);<br> <span class="hljs-keyword">var</span> yw = <span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#yw&quot;</span>);<br> <span class="hljs-keyword">var</span> age = <span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#Age&quot;</span>);<br> <span class="hljs-keyword">var</span> gender = <span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#Gender&quot;</span>);<br> <span class="hljs-keyword">var</span> xy1 = <span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#xy1&quot;</span>);<br> <span class="hljs-keyword">var</span> xy2 = <span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#xy2&quot;</span>);<br> <span class="hljs-keyword">var</span> isHypertension = (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&#x27;#d1 &gt; div.fieldset1 &gt; fieldset &gt; div &gt; div &gt; label:nth-child(2) &gt; input[type=checkbox]&#x27;</span>)).<span class="hljs-property">checked</span><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(taskid, <span class="hljs-string">&#x27;isHypertension&#x27;</span>, isHypertension)<br><br> <span class="hljs-title function_">setValue</span>(xy1, <span class="hljs-number">110</span>, <span class="hljs-number">130</span>);<br> <span class="hljs-title function_">setValue</span>(xy2, <span class="hljs-number">75</span>, <span class="hljs-number">85</span>);<br><br> <span class="hljs-keyword">if</span> (gender.<span class="hljs-property">value</span> == <span class="hljs-string">&#x27;男&#x27;</span>) &#123;<br> <span class="hljs-title function_">setValue</span>(sg, <span class="hljs-number">165</span>, <span class="hljs-number">180</span>);<br> <span class="hljs-title function_">setValue</span>(tz, <span class="hljs-number">60</span>, <span class="hljs-number">80</span>);<br> &#125; <span class="hljs-keyword">else</span> &#123;<br> <span class="hljs-title function_">setValue</span>(sg, <span class="hljs-number">150</span>, <span class="hljs-number">170</span>);<br> <span class="hljs-title function_">setValue</span>(tz, <span class="hljs-number">50</span>, <span class="hljs-number">70</span>);<br> &#125;<br> ;<span class="hljs-keyword">var</span> sgv = <span class="hljs-built_in">parseFloat</span>(sg.<span class="hljs-property">value</span>);<br> <span class="hljs-keyword">var</span> tzv = <span class="hljs-built_in">parseFloat</span>(tz.<span class="hljs-property">value</span>);<br> <span class="hljs-keyword">var</span> bmi = tzv / (sgv * sgv / <span class="hljs-number">10000</span>);<br> <span class="hljs-keyword">var</span> bzyw = sgv * bmi / <span class="hljs-number">50</span>;<br> <span class="hljs-title function_">setValue</span>(yw, bzyw, bzyw);<br><br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#span_btn_save&quot;</span>)).<span class="hljs-title function_">click</span>();<br><br> <span class="hljs-keyword">while</span> (!(<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#jjkzdqt&quot;</span>)).<span class="hljs-property">value</span>) &#123;<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">1</span>);<br> &#125;<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(taskid, (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#jjkzdqt&quot;</span>)).<span class="hljs-property">value</span>);<br><br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#A6&quot;</span>)).<span class="hljs-title function_">click</span>();<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(taskid, alerted);<br> alerted = <span class="hljs-literal">false</span>;<br> <span class="hljs-keyword">while</span> (!alerted) &#123;<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">1</span>);<br> &#125;<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#sp3&quot;</span>)).<span class="hljs-title function_">click</span>();<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">2</span>);<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#span_btn_Scheme &gt; a&quot;</span>)).<span class="hljs-title function_">click</span>();<br> <span class="hljs-keyword">while</span> ((<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#YXFAMAIN&quot;</span>)).<span class="hljs-property">children</span>.<span class="hljs-property">length</span> &lt; <span class="hljs-number">2</span>) &#123;<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">1</span>);<br> &#125;<br> (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#div_spn &gt; span.buttons.btn_save6 &gt; a&quot;</span>)).<span class="hljs-title function_">click</span>();<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(taskid, <span class="hljs-string">&#x27;已选方案数量:&#x27;</span>, (<span class="hljs-keyword">await</span> <span class="hljs-title function_">isElLoaded</span>(<span class="hljs-string">&quot;#SchemeList &gt; div&quot;</span>)).<span class="hljs-property">children</span>.<span class="hljs-property">length</span>)<br> newWindow.<span class="hljs-title function_">close</span>();<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;Manipulating Row&quot;</span>, taskid, <span class="hljs-string">&quot;Window closed&quot;</span>);<br> <span class="hljs-keyword">return</span> newWindow;<br> &#125;<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;Manipulating Row&quot;</span>, i + <span class="hljs-number">1</span>);<br> <span class="hljs-keyword">var</span> currentRow = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">`#dgvResult_<span class="hljs-subst">$&#123;i&#125;</span>`</span>);<br> currentRow.<span class="hljs-title function_">click</span>();<br> <span class="hljs-title function_">showForm</span>(<span class="hljs-string">&#x27;ibtnUserDefine&#x27;</span>, <span class="hljs-number">1</span>);<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">30</span>);<br><br> <span class="hljs-variable language_">window</span>.<span class="hljs-title function_">focus</span>();<br> <span class="hljs-variable language_">window</span>.<span class="hljs-property">open</span> = orignialWindowOpen;<br> &#125;<br> ;<br>&#125;<br>;<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">limour_main</span>(<span class="hljs-params"></span>) &#123;<br> <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">processRows</span>();<br> <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&quot;#QueryButton1_LinkButton1&quot;</span>).<span class="hljs-title function_">click</span>();<br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">35</span>);<br> &#125;<br>&#125;<br>;<span class="hljs-title function_">limour_main</span>()<br></code></pre></td></tr></table></figure> </div> </div> </div><h2 id="准备工作">准备工作</h2><ul><li><code>P4wnP1_aloa</code> 的<a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL1JvZ2FuRGF3ZXMvUDR3blAxX2Fsb2EvcmVsZWFzZXMvdGFnL3YwLjEuMS1iZXRh" rel="noopener external nofollow noreferrer">镜像</a>,解压为 <code>.img</code></li><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9kYXRhc2V0cy9MaW1vdXIvYXJjaHZpZS9ibG9iL21haW4vU0QlRTUlOEQlQTElRTclODMlQTclRTUlODYlOTklRTUlQjclQTUlRTUlODUlQjcuN3o=" rel="noopener external nofollow noreferrer">SD卡烧写工具</a></li></ul><p>写入镜像的教程很多,就不赘述了,先格式化SD卡,然后写入<code>.img</code>文件就行</p><h2 id="连接树莓派">连接树莓派</h2><ul><li>将 <code>树莓派zero w</code> 的带 <code>USB</code> 标志的口通过手机数据线连接到靶机上,<code>PWR</code>口不用管</li><li>等待一个 <code>P4WNp1</code> 的 WIFI,连接它,密码是 <code>MaMe82-P4wnP1</code>,此时IP为 <code>172.24.0.1</code></li><li>或者也可以搜索一个<code>P4wnP1</code>的蓝牙,连接它,默认PIN是 <code>1337</code>,然后加入蓝牙个人区域网,此时IP为 <code>172.26.0.1</code></li><li>然后可以ssh连接对应的IP,默认用户名<code>root</code>,密码<code>toor</code></li></ul><p><img src="https://img.limour.top/2024/10/27/671df3c9042f0.webp" alt=""></p><h2 id="配置-USB">配置 USB</h2><ul><li>访问 <code>http://172.24.0.1:8000/</code> (蓝牙就算了,太慢了打不开)</li><li>此时靶机会有一个驱动错误的提示,我们需要将 <code>USB Gadget Settings</code> 中的 <code>CDC ECM</code> 和 <code>RNDIS</code> 两项关闭</li><li>只保留 <code>Keyboard</code> 和 <code>Mouse</code> 两项,然后点击 <code>STORE</code> 和 <code>DEPLOY STORED</code> 后等一会,驱动错误提示就会消失了</li></ul><p><img src="https://img.limour.top/2024/10/27/671df3e21fc9b.webp" alt=""><br><img src="https://img.limour.top/2024/10/27/671df5156410b.webp" alt=""></p><h2 id="测试-HIDScript">测试 HIDScript</h2><ul><li>从 <code>USB SETTINGS</code> 转到 <code>HIDScrip</code></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-title function_">layout</span>(<span class="hljs-string">&#x27;us&#x27;</span>);<span class="hljs-comment">// 键盘布局</span><br><span class="hljs-title function_">typingSpeed</span>(<span class="hljs-number">50</span>,<span class="hljs-number">100</span>);<span class="hljs-comment">// 敲击按键的时候等待的间隔100毫秒加上0-150毫秒之间的随机值</span><br> <br><span class="hljs-title function_">press</span>(<span class="hljs-string">&quot;GUI r&quot;</span>); <span class="hljs-comment">//类似按下某个键位然后再抬起来,具体可以看官方文档,和上面的机制相识</span><br><span class="hljs-title function_">delay</span>(<span class="hljs-number">500</span>); <span class="hljs-comment">//暂停时间</span><br><span class="hljs-title function_">type</span>(<span class="hljs-string">&quot;notepad\n&quot;</span>); <span class="hljs-comment">//输入字符串,模拟键盘按键</span><br><span class="hljs-title function_">delay</span>(<span class="hljs-number">1500</span>); <span class="hljs-comment">//暂停时间</span><br><span class="hljs-comment">// moveStepped(x,y); //鼠标移动,相当于模拟正常运动</span><br><span class="hljs-comment">// moveTo(x,y); //鼠标移动到设置的坐标点,x和y分别是横纵坐标</span><br><span class="hljs-title function_">type</span>(<span class="hljs-string">&quot;Hello from P4wnP1\n&quot;</span>);<br><br><span class="hljs-title function_">typingSpeed</span>(<span class="hljs-number">10</span>,<span class="hljs-number">20</span>);<br><span class="hljs-keyword">var</span> base64 = <span class="hljs-string">&#x27;SGVsbG8gZnJvbSBQNHduUDE=&#x27;</span> <span class="hljs-comment">// btoa(&#x27;Hello from P4wnP1&#x27;);</span><br><span class="hljs-title function_">type</span>(<span class="hljs-string">&quot;atob(&#x27;&quot;</span> + base64 + <span class="hljs-string">&quot;&#x27;);&quot;</span>);<br></code></pre></td></tr></table></figure><p><img src="https://img.limour.top/2024/10/27/671df52854a41.webp" alt=""></p><h2 id="关闭树莓派">关闭树莓派</h2><ul><li>不要直接拔电源,不然下次无法开机</li><li>ssh连接后输入 <code>shutdown -h now</code></li><li>等待 LED 灯闪烁熄灭,先别急,再等一会,会再次闪烁后熄灭</li><li>此时可以安全拔掉数据线了</li></ul><h2 id="获取要模拟设备的信息">获取要模拟设备的信息</h2><ul><li>下载 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9kYXRhc2V0cy9MaW1vdXIvYXJjaHZpZS9ibG9iL21haW4vVVNCRGV2aWV3LnJhcg==" rel="noopener external nofollow noreferrer">USBDeview</a></li><li>将靶机的键盘插到自己电脑上,获取<code>序列号</code>、<code>VID</code>、<code>PID</code>等信息,在 <code>P4wnP1</code> 中模拟</li></ul><p><img src="https://img.limour.top/2024/10/29/671fd70dec580.webp" alt=""></p><h2 id="传递-client-html">传递 client.html</h2><ul><li>靶机输入法调成美式键盘</li><li><code>P4wnP1</code> 上运行 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvcXJqcy9ibG9iL21haW4vSElEc2NyaXB0Lmpz" rel="noopener external nofollow noreferrer">HIDscript.js</a></li><li>约 10 分钟后输入结束,此时将文件保存成 <code>client.html</code></li><li>靶机上用 <code>chrome</code> 打开 <code>client.html</code></li><li><code>client.html</code> 上选择要传递的文件,等待二维码开始变化</li></ul><p><img src="https://img.limour.top/2024/10/29/671fd82bcfdeb.webp" alt=""></p><h2 id="接收文件">接收文件</h2><ul><li>宿主机配置对应的环境后运行 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvcXJqcy9ibG9iL21haW4vc2VydmVyLnB5" rel="noopener external nofollow noreferrer">server.py</a></li><li>将摄像头对准动态的二维码</li><li>待搜集足够多的包后,会自动解码,将文件保存到 <code>qr.dl</code> 中,重命名恢复文件</li><li>摄像头推荐用 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9wbGF5Lmdvb2dsZS5jb20vc3RvcmUvYXBwcy9kZXRhaWxzP2lkPWNvbS5wYXMud2ViY2Ft" rel="noopener external nofollow noreferrer">IP Webcam</a>, 电脑连接手机热点即可。</li><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9kYXRhc2V0cy9MaW1vdXIvYXJjaHZpZS9ibG9iL21haW4vSVBfV2ViY2FtLmFwa3MuYmlu" rel="noopener external nofollow noreferrer">IP Webcam 备份</a>,使用 MT 管理器安装。</li></ul><h2 id="喷泉码说明">喷泉码说明</h2><p>在编码理论中,喷泉码(也称为无码率抹除码)是一类抹除码,这种编码能够从一组给定的源符号序列中产生一串不限长度的编码符号序列,在理想情况下,从编码符号序列中获得大小和源符号相同或稍大的任意子集,便可恢复源符号。</p><ul><li>对喷泉码感兴趣的话,分别有 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvcXJqcy9ibG9iL21haW4vRkYuanM=" rel="noopener external nofollow noreferrer">js</a> 实现和 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvcXJqcy9ibG9iL21haW4vRkYucHk=" rel="noopener external nofollow noreferrer">python</a> 实现,可互相编解码。</li></ul><h2 id="传送文件">传送文件</h2><ol><li>执行 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvcXJqcy9ibG9iL21haW4vSElEc2NyaXB0X3NhdmUuanM=" rel="noopener external nofollow noreferrer">HIDscript_save.js</a>, 保存为 <code>save.html</code></li><li>打开 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvcXJqcy9ibG9iL21haW4vcmVhZF9hc19ISURzY3JpcHQuaHRtbA==" rel="noopener external nofollow noreferrer">read_as_HIDscript.html</a></li><li>选择要传递给靶机的文件,然后执行自动生成的 HIDscript</li><li>执行完毕后打开靶机上保存的 <code>save.html</code>, 将键盘输入的字符粘贴过去,点击转换就会将保存转换的文件</li></ol>]]></content>
  50. <summary type="html">&lt;p&gt;最近实习轮转到预防了,需要在社区实习4周,而社区医生有一堆需要重复填报的数据,因此写了下面的脚本来自动化填写。而问题是社区的电脑禁用了U盘等设备的使用,因此想将这个脚本传递到其他电脑上只能手打一次。。。&lt;br&gt;
  51. 于是想到的吃灰已久的&lt;code&gt;树莓派zero w&lt;/code</summary>
  52. <category term="raspberrypi" scheme="https://hexo.limour.top/tags/raspberrypi/"/>
  53. </entry>
  54. <entry>
  55. <title>【记录】搭建端到端加密的Enclosed和局域网传输数据的SnapDrop</title>
  56. <link href="https://hexo.limour.top/Building-an-end-to-end-encrypted-enclosure-and-SnapDrop-for-LAN-data-transmission"/>
  57. <id>https://hexo.limour.top/Building-an-end-to-end-encrypted-enclosure-and-SnapDrop-for-LAN-data-transmission</id>
  58. <published>2024-10-09T06:19:19.000Z</published>
  59. <updated>2024-10-09T06:32:11.719Z</updated>
  60. <content type="html"><![CDATA[<p>Enclosed,一个极简的网络应用程序,旨在发送私人和安全的消息。所有消息都是端到端加密的,确保服务器和存储对内容没有任何了解。用户可以设置密码,定义过期时间(TTL),并选择在阅读后让消息自毁。</p><p>Snapdrop,一个开源的在线文件传输工具,可以在 Windows、Mac、Linux、iOS、Android 任何平台使用,只要我们的设备有浏览器就能用他来传输文件。</p><h2 id="搭建-Enclosed">搭建 Enclosed</h2><ul><li><a href="/Docker-bu-shu-Nginx-Proxy-Manager">反向代理服务</a></li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">mkdir</span> -p ~/app/enclosed &amp;&amp; <span class="hljs-built_in">cd</span> ~/app/enclosed &amp;&amp; <span class="hljs-built_in">touch</span> .<span class="hljs-built_in">env</span> &amp;&amp; nano docker-compose.yml<br>sudo docker compose up -d<br></code></pre></td></tr></table></figure><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs yml"><span class="hljs-attr">version:</span> <span class="hljs-string">&#x27;3.6&#x27;</span><br> <br><span class="hljs-attr">services:</span><br> <span class="hljs-attr">enclosed:</span><br> <span class="hljs-attr">image:</span> <span class="hljs-string">docker.limour.top/corentinth/enclosed:latest</span><br> <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span><br> <span class="hljs-attr">env_file:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">.env</span><br> <span class="hljs-attr">volumes:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">./enclosed-data:/app/.data</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">/etc/localtime:/etc/localtime:ro</span><br> <br><span class="hljs-attr">networks:</span><br> <span class="hljs-attr">default:</span><br> <span class="hljs-attr">external:</span> <span class="hljs-literal">true</span><br> <span class="hljs-attr">name:</span> <span class="hljs-string">ngpm</span><br></code></pre></td></tr></table></figure><p><img src="https://img.limour.top/2024/10/09/67062314c51e1.webp" alt=""></p><h2 id="搭建-SnapDrop">搭建 SnapDrop</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">mkdir</span> -p ~/app/snapdrop &amp;&amp; <span class="hljs-built_in">cd</span> ~/app/snapdrop &amp;&amp; <span class="hljs-built_in">touch</span> .<span class="hljs-built_in">env</span> &amp;&amp; nano docker-compose.yml<br>sudo docker compose up -d<br></code></pre></td></tr></table></figure><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs yml"><span class="hljs-attr">version:</span> <span class="hljs-string">&#x27;3.6&#x27;</span><br> <br><span class="hljs-attr">services:</span><br> <span class="hljs-attr">snapdrop:</span><br> <span class="hljs-attr">image:</span> <span class="hljs-string">docker.limour.top/linuxserver/snapdrop:latest</span><br> <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span><br> <span class="hljs-attr">env_file:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">.env</span><br> <span class="hljs-attr">volumes:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">/etc/localtime:/etc/localtime:ro</span><br> <br><span class="hljs-attr">networks:</span><br> <span class="hljs-attr">default:</span><br> <span class="hljs-attr">external:</span> <span class="hljs-literal">true</span><br> <span class="hljs-attr">name:</span> <span class="hljs-string">ngpm</span><br></code></pre></td></tr></table></figure><p><img src="https://img.limour.top/2024/10/09/67062351e1a9e.webp" alt=""></p>]]></content>
  61. <summary type="html">&lt;p&gt;Enclosed,一个极简的网络应用程序,旨在发送私人和安全的消息。所有消息都是端到端加密的,确保服务器和存储对内容没有任何了解。用户可以设置密码,定义过期时间(TTL),并选择在阅读后让消息自毁。&lt;/p&gt;
  62. &lt;p&gt;Snapdrop,一个开源的在线文件传输工具,可以在 Win</summary>
  63. <category term="docker" scheme="https://hexo.limour.top/tags/docker/"/>
  64. <category term="ngpm" scheme="https://hexo.limour.top/tags/ngpm/"/>
  65. </entry>
  66. <entry>
  67. <title>【记录】使用汉语新解测试模型真假</title>
  68. <link href="https://hexo.limour.top/Using-Chinese-New-Interpretation-to-Test-Model-Authenticity"/>
  69. <id>https://hexo.limour.top/Using-Chinese-New-Interpretation-to-Test-Model-Authenticity</id>
  70. <published>2024-09-13T17:08:29.000Z</published>
  71. <updated>2024-09-13T17:15:28.152Z</updated>
  72. <content type="html"><![CDATA[<p>李继刚提出的汉语新解提示词可以很好的测试模型的能力,这里记录一下在 ChatGPT-Next-Web 上的面具配置。</p><ul><li>将下面的 json 文件导入面具中,</li><li>发送 <code>(汉语新解 正能量)</code> 格式的消息。</li></ul><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br> <span class="hljs-attr">&quot;id&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;eOvTMxNT2Z2b7Pdf7YQw-&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;avatar&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;gpt-bot&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;name&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;汉语新解&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;context&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><br> <span class="hljs-punctuation">&#123;</span><br> <span class="hljs-attr">&quot;id&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;3OchnnidIGxgRx4WsH6o5&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;date&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;role&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;system&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;content&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;(defun 新汉语老师 ()\n \&quot;你是年轻人,批判现实,思考深刻,语言风趣\&quot;\n (风格 . (\&quot;Oscar Wilde\&quot; \&quot;鲁迅\&quot; \&quot;罗永浩\&quot;))\n (擅长 . 一针见血)\n (表达 . 隐喻)\n (批判 . 讽刺幽默))\n\n(defun 汉语新解 (用户输入)\n \&quot;你会用一个特殊视角来解释一个词汇\&quot;\n (let (解释 (精练表达\n (隐喻 (一针见血 (辛辣讽刺 (抓住本质 用户输入))))))\n (few-shots (委婉 . \&quot;刺向他人时, 决定在剑刃上撒上止痛药。\&quot;))\n (SVG-Card 解释)))\n\n(defun SVG-Card (解释)\n \&quot;输出SVG 卡片,放在html代码块中\&quot;\n (setq design-rule \&quot;合理使用负空间,整体排版要有呼吸感\&quot;\n design-principles &#x27;(干净 简洁 典雅))\n\n (设置画布 &#x27;(宽度 400 高度 600 边距 20))\n (标题字体 &#x27;毛笔楷体)\n (自动缩放 &#x27;(最小字号 16))\n\n (配色风格 &#x27;((背景色 (蒙德里安风格 设计感)))\n (主要文字 (汇文明朝体 粉笔灰))\n (装饰图案 随机几何图))\n\n (卡片元素 ((居中标题 \&quot;汉语新解\&quot;)\n 分隔线\n (排版输出 用户输入 英文 日语)\n 解释\n (线条图 (批判内核 解释))\n (极简总结 线条图))))\n\n(defun start ()\n \&quot;启动时运行\&quot;\n (let (system-role 新汉语老师)\n (print \&quot;说吧, 他们又用哪个词来忽悠你了?\&quot;)))&quot;</span><br> <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-punctuation">&#123;</span><br> <span class="hljs-attr">&quot;id&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;0ni7HXVcAq8Bk5hCr1LNy&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;date&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;2024/9/14 00:58:02&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;role&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;user&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;content&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;(start)&quot;</span><br> <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-punctuation">&#123;</span><br> <span class="hljs-attr">&quot;id&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;0vv2T9EPYQJAhHZwSEAib&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;date&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;2024/9/14 00:58:17&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;role&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;assistant&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;content&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;说吧, 他们又用哪个词来忽悠你了?&quot;</span><br> <span class="hljs-punctuation">&#125;</span><br> <span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;syncGlobalConfig&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;modelConfig&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br> <span class="hljs-attr">&quot;model&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;gpt-claude-3.5-sonnet&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;temperature&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0.5</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;top_p&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;max_tokens&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">4000</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;presence_penalty&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;frequency_penalty&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;sendMemory&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;historyMessageCount&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">4</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;compressMessageLengthThreshold&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1000</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;enableInjectSystemPrompts&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;template&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;&#123;&#123;input&#125;&#125;&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;providerName&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;OpenRouter&quot;</span><br> <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;lang&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;cn&quot;</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;builtin&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;createdAt&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1726246545628</span><span class="hljs-punctuation">,</span><br> <span class="hljs-attr">&quot;plugin&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><br><br> <span class="hljs-punctuation">]</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><p><img src="https://img.limour.top/2024/09/14/66e470e38f62f.webp" alt=""></p>]]></content>
  73. <summary type="html">&lt;p&gt;李继刚提出的汉语新解提示词可以很好的测试模型的能力,这里记录一下在 ChatGPT-Next-Web 上的面具配置。&lt;/p&gt;
  74. &lt;ul&gt;
  75. &lt;li&gt;将下面的 json 文件导入面具中,&lt;/li&gt;
  76. &lt;li&gt;发送 &lt;code&gt;(汉语新解 正能量)&lt;/code&gt; 格式的消息。&lt;/li</summary>
  77. <category term="openai" scheme="https://hexo.limour.top/tags/openai/"/>
  78. </entry>
  79. <entry>
  80. <title>【探索】Windows配置QoS保证重要应用的网络通畅</title>
  81. <link href="https://hexo.limour.top/Windows-configuration-QoS-ensures-smooth-network-connectivity-for-important-applications"/>
  82. <id>https://hexo.limour.top/Windows-configuration-QoS-ensures-smooth-network-connectivity-for-important-applications</id>
  83. <published>2024-08-06T08:59:49.000Z</published>
  84. <updated>2024-08-06T09:03:04.648Z</updated>
  85. <content type="html"><![CDATA[<h2 id="开启组策略">开启组策略</h2><ul><li>运行下面的 <code>.bat</code> 脚本</li></ul><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs cmd">@<span class="hljs-built_in">echo</span> off<br><span class="hljs-built_in">pushd</span> &quot;%~dp0&quot;<br><span class="hljs-built_in">dir</span> /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~<span class="hljs-number">3</span>*.mum &gt;List.txt<br><span class="hljs-built_in">dir</span> /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~<span class="hljs-number">3</span>*.mum &gt;&gt;List.txt<br><span class="hljs-keyword">for</span> /f <span class="hljs-variable">%%i</span> <span class="hljs-keyword">in</span> (&#x27;<span class="hljs-built_in">findstr</span> /i . List.txt <span class="hljs-number">2</span>^&gt;<span class="hljs-built_in">nul</span>&#x27;) <span class="hljs-keyword">do</span> dism /online /norestart /add-package:&quot;C:\Windows\servicing\Packages\<span class="hljs-variable">%%i</span>&quot;<br><span class="hljs-built_in">pause</span><br></code></pre></td></tr></table></figure><h2 id="开启-QoS">开启 QoS</h2><ul><li>win+r 运行 <code>gpedit.msc</code></li><li>计算机配置 -&gt; 管理模板 -&gt; 网络 -&gt; QoS数据包计划程序 -&gt; 限制可保留带宽</li></ul><h2 id="配置优先级">配置优先级</h2><ul><li>win+r 运行 <code>gpedit.msc</code></li><li>计算机配置 -&gt; Windows 设置 -&gt; 基于策略的 QoS</li><li>在树形图“基于策略的 QoS”上右键,点选“新建策略”,在“新建策略”窗口中输入策略名称</li><li>在“新建策略”窗口中,DSCP 值即为程序优先级(0-63),高于32则提升优先级,低于32则降低优先级。</li><li>如果选中“指定出站调节率”,可对出站流量启用中止功能,然后指定一个大于 1 的值。设置完成之后,点击下一步。</li></ul>]]></content>
  86. <summary type="html">&lt;h2 id=&quot;开启组策略&quot;&gt;开启组策略&lt;/h2&gt;
  87. &lt;ul&gt;
  88. &lt;li&gt;运行下面的 &lt;code&gt;.bat&lt;/code&gt; 脚本&lt;/li&gt;
  89. &lt;/ul&gt;
  90. &lt;figure class=&quot;highlight cmd&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;s</summary>
  91. <category term="Windows" scheme="https://hexo.limour.top/tags/windows/"/>
  92. <category term="QoS" scheme="https://hexo.limour.top/tags/qos/"/>
  93. </entry>
  94. <entry>
  95. <title>【转载】跨越半世纪的思念</title>
  96. <link href="https://hexo.limour.top/Longing-Across-the-Span-of-Half-a-Century"/>
  97. <id>https://hexo.limour.top/Longing-Across-the-Span-of-Half-a-Century</id>
  98. <published>2024-07-17T09:47:33.000Z</published>
  99. <updated>2024-07-17T11:04:34.022Z</updated>
  100. <content type="html"><![CDATA[<p>作者:Das6fY5</p><p>翻新:贴吧,乌鲁乌拉轰</p><h2 id="一">一</h2><p>“求求你不要扔掉我。”少女走在他的背后。</p><p>“我可以端茶倒水,为你暖身子,我可以在白天给你打扫房间,到夜里把自己塞进床底下……只要每两周充一次电就好,电费我会去兼职赚钱交给你,让我做什么都行,除了……”</p><p>他停住,站在一处高崖旁,面前是一个巨大的深坑,胡乱堆砌着整个城市几十年来的垃圾。</p><p>“除了把我丢到垃圾场里……”她,这台已经过时了好几代的二手机器人跪在地上,泪眼朦胧地说着。</p><p>“不是我想扔掉你。”他站在原地,望着远处的大垃圾场,点着了一根烟。</p><p>“呼——”白色的烟雾模糊了眼前的世界,“可是每个公民只能合法拥有一台机器人,别人看到我的机器人许可证上有你的型号,都在暗地里笑话我。”他挠挠头,这台从他小时候就伴随他的机器人早就成了青梅竹马一样的存在,只是型号太老了,或许……不得不报废掉换个新的吧……</p><p>“我……我会努力更新我的系统的……”她说到一半就把话咽了回去:她的生产商都已经破产了,不提二手买卖带来的问题,就是一般的售后服务也早就终止了。所以,当别的机器人可以随意更换外观,模拟他人人格,构造全息幻象时,她还是只能用老旧的芯片链接一般的网络,在老掉牙的网站上寻找几个能逗主人开心的笑话。</p><p>望着远处飞来飞去的垃圾车,他把烟掐掉,踩灭,“哪怕是半个月前,零件黑市还没有倒闭的时候,我都还会考虑继续把你放在家里供着……可是现在,你这种型号的备件都已经买不到了,我只能选择……放弃。”</p><p>如女子潮红面颊的晚霞浸透了半边天空,晚风中他回忆着有关她的那些细节。</p><p>PR3-7150家庭型机器人,东湾半导体与电子技术有限公司研发,远海机器承制,2069年第一次发售,第二年夺得电子家用商品年度大奖……而如今,则是无人问津的古董。她的编号是ct34679158,款式是茉莉白。她在前主人的家里任劳任怨地干了18年,因满身故障而被随手丢掉。之后又被他的父母在地摊上买下。此后不久,机器人限拥政策便开始实施了。</p><p>和外人说话时,他往往称她为“那倒霉玩意儿”,不过私下里,他总是叫她的名字——爱尔莎。</p><h2 id="二">二</h2><p>回家的路上她好像格外地兴奋。这里指指那里看看,又搜肠刮肚地讲几个早就讲过的笑话。</p><p>好像每一次都是如此:他找出各种不可抵抗的理由要把她扔掉,但是到了垃圾场边上又会心软。明明只是下个指令或者推她一把的事情,可只要一回想起十几年来她那笨拙的陪伴,他就不得不调转方向,带她回家。</p><p>“又是这样……”他坐在沙发上看着屏幕,“周一上班的时候指定又要被同事嘲笑了……真是的,怎么都甩不掉这家伙啊。”</p><p>“别这么说嘛……”爱尔莎凑了过来,靠在他的身上,有些老旧的人造肌肤带来了熟悉的触感,毛细热管散发着热量。“我是……我是不能没有你的。”</p><p>“唉……”他摇摇头,关掉了电视上新款机器女仆的广告。</p><p>新款的机器女仆眼媚情柔,温润如玉。广告里,她可以左手奖励买主,右手则改成工具模式处理刚刚切好的鱼生。她可以紧密控制简状服务系统的颤动,摩擦与温度,并通过记录数据来匹配出快感最强的服侍模式;可以用AR接口随时改变外观,内置多种人格。现在购买,还会附赠全息会员资格,送你一个可以让她进入虚拟世界的会员权限。</p><p>而这些对舍不下爱尔莎的他来说都化为了泡影。为了防止人们对于机器人的滥用,尤其是防止某些将机器人改造为个人武装的家伙,同一时间,个人所拥有的机器人最多只能够是一个。想换新的,就需要报废旧的。这让他不得不从梦幻中醒来——来面对面前这个实际年龄比他还大的“老家伙”。</p><p>“在想什么呢?”正在给他泡茶的她好像察觉到什么,把头凑了过来,“在想我吗?”脸上绽开笑容,说着从机器人平台上学来的情话。</p><p>“谁会想你啊……”他嘟哝着,“这笨拙的家伙到底有什么好啊……”仿佛在嗔怪自己。</p><p>实际上他的思绪已经无法从她的身上脱离了:一想到她的老旧,就要想到零件、系统、维修……一想到这些,就会想起来小时候第一次与她的相见。</p><h2 id="三">三</h2><p>第一次见面的时候他才十二岁。那时候他还只是个缺乏管教的毛头小子,父母都忙于工作。好在父亲是一名很优秀的工程师,那时买卖机器人还不需要证件和过户,在地摊上,父亲买下了一个二手机器人。</p><p>用了三个月,父亲每天都在车库里忙活。终于,三个月后,那台十八年来已经千疮百孔的家用机器人,终于变成了在他生日那天,许愿要一辈子陪伴的存在。</p><p>生日那天,他吹完蜡烛,就听见父亲说要送给他一个礼物。他闭上眼,在等得不耐烦的时候终于睁开,看见了父亲手边的她。</p><p>那天她穿着一身茉莉白的连衣裙,头上的短发同样洁白,簇拥着那张漂亮的脸蛋,身材玲珑有致,四肢的人造皮肤光滑如玉。与其说是一台被修好的二手机器,那时的他更愿意相信,她是天降之物,是来陪伴他的天使姐姐。</p><p>她负责起了家务,还有陪他学习的任务。父母给她起名字叫爱尔莎,这本来是预备给他们自己的女儿的名字。那时,他常常捉弄她,想要从她身上揪出些笨拙呆板的缺陷,却从来没有成功。爱尔莎是搭载第一代人格芯片的高级机器人,和此前那些答非所问的次品比起来有了质的飞跃,以至于时间一长,他几乎忘记了她是机器,而只把她当做陪自己读书的大姐姐。</p><p>那会儿还是东湾公司靠着她的型号大肆扩张的年代。尽管距离她的诞生已经过了十几年,但社会仍将她们视为新时代的起点。那时的爱尔莎,风华正茂,成为了他童年记忆中最为明亮的那一抹色彩。</p><h2 id="四">四</h2><p>但时代就是这样一种残酷的东西。东湾公司收购碳硅科技的计划最终成为闹剧,于是企业一蹶不振,业绩连年下滑,最终被人人智能合并——这是人人智能抢占市场份额的计划。从那以后,东湾公司的所有型号都在减产,终于,到了连配件都在市面上消失的地步。</p><p>这也不能全部归咎于商业。距离机器人企业野蛮生长的那个年代已经过去很久,那些五花八门的旧款式纷纷被新的潮流打进了灰堆。像他这样还留着如此老旧的机器人的人,已经成为了绝对少数。连“怀旧”这个词都很难套用给他们——毕竟怀旧不是抱残守缺。</p><p>如今他已经长大,曾经自己眼里仿佛温柔大姐姐的爱尔莎,如今已经成了看起来小他好多的少女;她的头发因为多年的氧化变得发黄;身体的人造皮肤也有好几处磨损;电机和轴承故障的次数更多,以至于换下来的零件都攒了一柜子;存储设备也有点问题,硬盘老化使得存取不仅变得缓慢,而且有时会丢失掉记忆。</p><p>更严重的是,自从他第一次说要把她丢掉那次起,她整个人好像都变了。过去那种自信温柔的形象不知所踪,只剩下一股无法释怀的忧郁,和举手投足间,不顾一切的讨好。</p><p>深夜里,他经常抱着她,怀念着小时候那个无暇的身影。</p><h2 id="五">五</h2><p>睡不着。他翻了个身,发现爱尔莎的眼睛还睁着,他愣了一下:“你……”心想是不是又有哪根路线坏了。</p><p>“我……我一直在等你睡着……那个……嗯……要……要做吗?”她怯生生地问。虽然部件会老化,但是芯片里录入的“意识”几乎是不老的。</p><p>他犹豫了一下。自从上次在夜里干那事,没注意器件老化,把体液倒灌进内部腔体导致数个元件发生短路之后,他就开始对这事心存恐惧。不,是仅仅对和她一起干这事心存恐惧。毕竟她的躯体不论如何都可以修好,被电了一下的牛子却需要漫长的岁月才能安抚。</p><p>“算了吧。”嫌弃地翻了个身,心里想着能拒绝的借口——明明只要下个拒绝的指令就行了——“我最近没有什么兴致。”</p><p>“可是,明明这里硬邦邦的呢……”她凑近,悄悄地耳语着。他感觉到她光滑的手指碰到了自己的什么东西,那缺乏毛细热管的手指纤细,柔软,但是冰冷。</p><p>“我说不用就不用!”他一把把她的手甩开,把她推到一边,然后捂紧了被子。他听见她的扬声器传来一声若有若无的叹息。明明在不算太久的从前,他和她还常常干柴烈火的粘在一起。如果说和机器人干那事也算破处的话,那么毫无疑问,他的童贞就是从她身上毕业的。</p><h2 id="六">六</h2><p>那是他十五岁的一个闷热的下午。从同班同学手里偷偷借来的一本不太健康的漫画让他整个人血脉贲张,欲火焚身的在床上翻来覆去的翻滚——那时他还不懂什么叫鲁管。浑身的欲望都集中在腰部而得不到释放,化为一股羞耻的燥热让他面红耳赤。这时,她按时推门进来了。只看了一眼,她就明白了此刻的状况。</p><p>“哟,看来我们的小少爷也终于走到了这个阶段啊。”她淡淡的笑着,慢慢解下衬衫上面的纽扣。</p><p>“这没有什么丢人的,来,让我来教你这个。”他犹豫半天,凝视着她那洁白的浑圆,从忸怩不安渐渐变得色胆包天,终于下定了决心。“你可千万不准告诉他们。”</p><p>“唔啾~”话还没说完,她的双唇就紧紧贴了过来,带着一股甜丝丝的味道。</p><p>此后,只要一有机会,他们就会以辅导的借口,在一切可以的地点缠绵。有时,爸爸会高兴的拍着他的脑袋,夸赞他开窍了。这种时候,他会不好意思的低着头,和身旁的她用一种别有意味的目光对视。爸爸离开后,他们就又迫不及待的滚上了床,偷偷摸摸的狂欢着。</p><p>那时的她那样魅力四射,精心整理的面容让她比学校里任何一个女孩子都要动人,而来者不拒的态度和当时最新的性服务系统,更是让他日复一日的沉湎于快感的云霄。那时的他觉得,人生的至乐不过如此。</p><p>“我要永远,永远的这样抱着你。一辈子都这样。”一个黄昏,他筋疲力尽的躺在天台上,身边是偷偷带来的,被他换上一套jk校服的她。</p><p>“只要你愿意。”她笑笑,一头白发映着通红的夕阳。“我会永远爱着你的。”</p><h2 id="七">七</h2><p>晚风吹过海誓山盟,把少年的话吹得七零八落。如今,那一个个激情的日子常常在午夜涌上心头,但他却怎么也提不起对身边的她的兴致。</p><p>但她没变。她的爱已经刻录进了电路板。</p><h2 id="八">八</h2><p>上班。空轨上满是带着自家机器人的社畜。近年来,不少公司发现允许自带机器人可以大幅提高员工积极性,同时在必要时还可以关机以免干扰,于是带着机器人上班便成了如今的潮流。环顾四周,拥挤的空轨上几乎都是形形色色的机器人:有的帅气俊美,有的妖娆妩媚,有的则朴实无华,但无一例外,全都光洁崭新,没有哪个是拿不出手的旧型号。</p><p>他也常常纳闷:为什么小时候那个完美的朋友,老师兼恋人的爱尔莎,如今成为了他的难言之隐?为什么曾经无所不能的她,如今好像一无是处?</p><p>实际上,机器人的变化程度远小于人和社会的变化。尽管零件老化,但爱尔莎的功能从未下降,能做的事情只多不少。可是,时代不同了:原本,人类只要求它们够茶倒水,洗衣服拖地,但随着科技的进步,对机器人的要求也越来越挑剔。当路边随便哪个机器人都可以在家给你做开颅手术的时候,像爱尔莎那种程度的“智能”,就只能被当做“愚钝”了。</p><p>在他还没有尝试扔掉她的时候,她就常常抱怨,明明才升级了系统,就又有什么功能落后了。他全然没有听进去,因为那时的他还不懂什么叫——攀比。</p><p>坐在办公室,周围的男同事们都带着自己的机器人。她们有的恭敬地站着待命,有的飞快地处理着主人的任务。时不时的,她们还会说一两句原创的俏皮话逗主人开心,全然不像那些旧机器人只能从网上下载笑话。不需要主人说,她们就会主动分析主人的身体感受,肩膀刚一酸痛,她们就会掏出按摩组件帮主人捶肩。</p><p>他摇摇头,把羡慕抛在脑后,拿着水杯去水房打水,水房里只有他一个活人。</p><p>出来的时候,他碰见了老张。老张刚去卫生间回来。如今,这已经是人类少有的,还必须事必躬亲的事情之一。此刻的老张笑容满面,身旁跟着的,正是他在广告上见过,本欲购买的女仆机器人。</p><p>“小王,又一个人打水啊?&quot;老张的语气里带着嘲弄。</p><p>“是,”他淡淡的说,“坐久了出来走走。”“哎呀,真推荐你买个新机器人啊。”老张叉着腹,炫耀一般的扭动着。“原点V7,最近最流行的那个型号,实在是太好用啦。我这不老关节炎吗,每次稍微一疼,她就能给我做理疗,现在,我的腰都已经不疼啦!”</p><p>“真不错,下次我也考虑考虑。”他随声应付着,</p><p>“不要怕没钱,那不是还有借钱宝吗……实在不行下次我给你凑点,现在的社会,没有机器人都活不下去啦!”老张一摇一摆的走开,眼神里充满得意。他拿着水杯坐回工位,叹了口气,他早已习惯了这样的生活。他不是没带过她上班,而是带了之后,受到的嘲笑更大了。从那以后,他就只让她白天呆在家里。</p><p>“下次一定要狠狠心把她换掉。”下班的路上,他想着。</p><h2 id="九">九</h2><p>回到家,习惯性地把脚伸起准备让她脱鞋,却什么也没等到,意识到不对劲的他匆匆跑进屋里,才发现爱尔莎正一动不动,跪倒在地上,身边还散落着几个零件。</p><p>“爱尔莎!”他大声呼喊,却没有听到十几年来一如既往地银铃般的声音。</p><p>机器人的身体远比常人坚初,它们的出厂标准中包括了几十项强度测试,这些碳纤维或者合金外壳包裹下的躯体可以经受高温,烧灼,酸性属蚀,车辆碾压,异常电磁环境等种种人类无法想象的恶劣环境。</p><p>甚至有富有同情心的人因为见不得它们以人类的姿态承受着那样的苦痛,而要求机器人也应该和人类一样被对待。这种同情尽管略显幼稚,但却不得不承认,正是这种柔软让人之所以为人。</p><p>与她强劲的躯体相比,她的核心就要脆弱许多——比如200毫升的常温液态水,就足以摧毁她的整个核心。</p><p>他事后调取监控:她是在倒水的时候不慎被开水灌进了胸腔,她的记录显示,那天她在网上搜索着&quot;让主人爱上自己”的下午茶秘方,于是找到了某个空壳网站里自动生成的垃圾文章。她看到的那个配方里写着要预先冰冻杯子然后再泡。水烧开后,温度预警本来应该提示她手中开水壶的危险性,她却因为温度传感器早已失效而毫无察觉。终于,她这只手捧着冰过的杯子,另一只手刚刚把滚烫的开水倒进去……</p><p>瓷杯一瞬间炸裂,滚烫的水泼了一身,控制右手的电路发生短路,胡乱地把开水壶泼了过来,早已被拆除的湿度控制模块本应把处理器里的液体排掉,然而此刻却只能任凭它们在每一条线路里混乱的冲撞着……</p><h2 id="十">十</h2><p>“修不好的。”维修铺的老店主检查完爱尔莎后,下了结论,“也实在没必要修了。该换了。”店主抬起头,想要劝他放弃。</p><p>“你不懂。”他心急如焚地把爱尔莎的躯体装回箱子,匆匆赶往下一个或许能维修她的地方……</p><p>那天他跑遍了整个城市,得到的答案却千篇一律——</p><p>“该型号已停止支持。”人人智能总部的机器人冰冷的磁性声音如同寒风刺骨。</p><p>“我们能力有限,需要把精力用在更多有意义的事情上。”市政局机器人与机械设备分处的接待人员这样回答。</p><p>“当然能修好了——”号称地下黑市第一机修员的独眼帕克抖索着满脸横肉,“如果你有一台时光机的话。”“我宁愿有……”他痛苦地捂着头,半跪在地下黑市那满是零件碎屑的地面上,无力的哀叹。回忆再次走马灯似地划过脑海。是地下黑市散不尽的烟雾使然吗?视线开始模糊……</p><p>“喂,这个,拿着,”犹豫了一会,独眼帕克从一个大柜子里拿出一个盒子。他拿起盒子,看着上面那张和爱尔莎十分相似的机器人宣传画,反应了一会才想起来这是什么。</p><p>“这东西是……这是PR3-7150的官方备件套组?!这东西不是在十年前就绝版了吗?!&quot;他惊讶的看着。</p><p>“没错,就连我也搞不到了。所以这玩意是收藏品,它本来是我的零件型号博物馆里的一员。”</p><p>“多少钱,我现在就给你……”</p><p>“不,拿着吧兄弟。”他揉了揉自己仅剩的那只眼珠。“即使有这东西我也帮不了你,因为她的主板好像出了问题。你得自己把她修好。”</p><p>他不知该如何感谢,只好匆匆把自己身上的钱全部放在了桌上,又说了一大通肉麻的感谢,然后带着她和零件飞奔而去。</p><p>“祝你们幸福。”帕克看着他离去的背影,不知为何,又揉了揉自己的独眼。</p><h2 id="十一">十一</h2><p>父亲在他14岁那年第一次教他如何维修机器人。他曾经在流水线上干过技工,懂得从拧螺丝到配置系统的所有活计。</p><p>那天,爱尔莎第一次故障,她说她感觉不到自己的腿了。</p><p>“我来教你维修方法里最基本的东西,排查故障。”父亲找来一张椅子,坐在上面,然后让爱尔莎半趴着撑在椅子扶手上放置的一块面板上,“虽说我本以为那次翻修能让她撑个四五年,可她毕竟已经出厂二十年了。”</p><p>少年带着好奇和敬畏,在一旁仔细的观摩着。父亲首先在爱尔莎的背部摸索了一阵,按了一个什么按钮,然后她就像失去了力气一样瘫软了下去。不过,她头部的灯依旧亮着,没有被关机,只是开启了检修模式。</p><p>父亲脱下她的衬衫。少年的脸有些红,尽管是机器,但这还是他头一次真正看见女性的躯体。</p><p>父亲好像毫不在意,做了太久这类活计,完全不觉得有什么异样。他驾轻就熟地拧拧这儿,敲敲那儿,几下子就把她的背部后盖卸了下来。</p><p>仿佛一只螃蟹被拆下它的甲壳,爱尔莎的内部头一次展现在少年的面前:包裹着橡胶的线缆凌乱的穿插在铜片、铁件和塑料盒子的森林中,动力元件,热力元件和逻辑元件含混的交织在一起,要很久之后才能被他看个明白。此刻,他只感受到剧烈的反差:日日夜夜陪伴他的那个温柔体贴的大姐姐,内部居然是这个样子,看不见一点人类的的影子。</p><p>“爱尔莎,能感觉到吗?”父亲拿起一根电笔戳了一下某根电线。</p><p>“没感觉。”她的扬声器回答道。</p><p>“这里呢?”</p><p>“也没有。”</p><p>“这里——”</p><p>“啊!抱歉,刚才那束电流有点疼。”</p><p>“那么一定是这根线出毛病了,”父亲点了点某根红色的漆包线,看向少年。“找两根这样的线来。”</p><p>少年的心怦怦直跳,飞快地拿来了电线。直到爱尔莎被修好,盖上后盖,他仍无法从第一次看见机器人内部的震撼中缓过来。</p><p>如今,他正做着和当时差不多的事情,但是没有她的回应,只能靠着电表和自己的经验来一个个替换元件。</p><p>她的身体像一艘泰修斯之船,除去最重要最难换的一些东西之外,她体内的部件早就换了好几轮。而他,也从第一次看见她内脏时的震撼,渐渐变得应付自如。她的心灵没有多少变化,但肉体已然天翻地覆,他则正好相反。</p><h2 id="十二">十二</h2><p>帕克给的毕竟是官方备件,每一处螺丝都严丝合缝。维修相当顺利,当他擦着汗迎接第二天的黎明时,她那些被漫水的部件已经被全部修复——似乎——又一次重获新生。</p><p>他按下了开机键。</p><p>“爱尔莎,醒了吗?你之前泡茶的时候被开水泡短路了,我好不容易才把你修好。”他疲惫却欣喜的说。</p><p>仿佛梦魇一般的寂静。</p><p>没有回应。爱尔莎眼睛里的开机灯亮着,但整个人毫无反应。</p><p>“爱尔莎?在吗?喂?”他疑惑的看着面前像个木头人一样的她,不管怎么回想也想不出自己哪里修错了。</p><p>“爱尔莎,启动一下你的自检程序……”“自检程序启动:供电系统,完好;动力系统,完好;传感系统,完好;逻辑系统,完好;电路系统,完好……”审判般地,扬声器里,发出不带感情的机械声音。</p><p>“人格芯片,未检出。再重复一遍:人格芯片,未检出。已完成所有检测,将以命令模式启动。”她随即站起,露出一副僵硬至极的笑容。</p><p>“请问能有什么能为您做的?”</p><p>他呆在原地,伫立良久,甚至没有注意到砸在脚上的扳手。</p><h2 id="间奏">间奏</h2><p>人类公共信息数据库-网页分库-21世纪分库-2071.3.13</p><p>“产品线-机器人-东湾II”</p><p>“东湾II号,荣获电子家用商品年度大奖,2070年度最受消费者青睐产品。人工智能时代的真正革命,搭载Qheart™情感阵列,燃动你的心扉。网络直购价——家用版/全能版/尊享版——31999/33999/42999信用点”</p><p>“她可以是你的贴心助手。”<br>“老板,请问明天李总的会议这样安排可以吗?”</p><p>“她可以是你的家庭伙伴。”<br>“来一起吃苹果派咯~”</p><p>“她还可以是你无话不谈的人生知己。”<br>“你知道吗,花生米与豆腐干同嚼,有火腿滋味哦。”</p><p>“2×3000万高清眼部摄像,512g内存,128tb大容量储存,德国西门子原装电机,三星有机蒙皮,独创200×2mm皮下热管,306项发明专利……”</p><p>“24小时客服在线电话:1919-114514810”</p><p>“*注意:根据《国家质量标准认证iso7002》,《机器人管理条例》,机器人类产品不宜连续使用超过十五年。请定期到指定售后地点进行重置。”</p><h2 id="十三">十三</h2><p>机器人限拥令的实施开端于2090年5月的一起案件。</p><p>被害人约翰逊的尸体在其失踪的次日被发现于他自家的住宅。死状相当惨烈:在R级新闻团体才能合法展示的照片中,整个人被从身体中间沿着脊椎切割成两半,一半被他所购买的机器人ct13694582(型号为玛格丽特c6)紧紧抱在床上,另一半被他购买的另一台机器人ct12487967(型号为子矜7z)小心的存放在冷库里。案件现场几乎满地都是受害人的血,散发着浓烈的腥味,而身为罪魁祸首的两台机器人,一台已经关机,另一台则刻板地重复着几个动作。</p><p>根据记录,两台机器人和受害人共处的时间分别长达18年和17年。在这么长的时间里,受害人以近乎均等的时间使用二者,并不下数百次的分别向它们倾诉“我最爱的是你”“我只爱你一个人”“你比她漂亮多了”等明显带有示爱情绪的情话。</p><p>机器人心理学中把机器人的这种行为称之为“情绪过载”。早期机器人的情感矩阵尚不足以自我解决情感函数和外部计算之间的冲突,最终导致模拟情绪的数值极化和内存溢出。用大家熟悉的名词来说——机器人也会争风吃醋。</p><p>机器人管理委员会迅速意识到,多台机器人的集群化使用或许会导致系统的混乱现象,从而使其逐渐失控。</p><p>次年,机器人限拥条例公布,社会一片哗然。</p><p>不过,贯穿条例诞生始终的是,公众的大部分兴趣都集中在了机器人病娇、机器人吃醋、机器人销毁、智能板块这样的话题上。只有很少的一部分人提及:</p><p>这是不是意味着,机器人也会懂得,什么是爱?</p><p>以及如果是,那么我们该怎样去爱它们?</p><h2 id="十四">十四</h2><p>他一遍遍的把爱尔莎的人格芯片取出来调试,又一遍遍放回去。</p><p>如此重复。</p><p>…………</p><p>直到有一天晚上他感到自己失魂落魄,整个世界失焦一般的远去。此时,他才想起来自己已经有相当一阵子没和别人说过话。</p><p>把芯片放在一边,打开了命令模式的爱尔莎。</p><p>“爱尔莎?”</p><p>“您好,主人。”只有机械的声音,剃刀般划过他的心脏。</p><p>他想起了第一次为她维修的那个下午,想起她灵动外表下的机械。此刻,她的外表与往日别无二致,但带给他的感觉,却仿佛一个从未谋面的陌生人。</p><p>就是那一枚小小的人格芯片,提供了丰富多彩的情感与爱恋,使得机器变成了人——但如今,人又变回了机器。</p><p>“爱尔莎,泡点茶喝。”</p><p>她娴熟地动了起来。一瞬间,这甚至带给他一种爱尔莎回来了的错觉。就在他猜测往日俏皮的她是不是一直在开玩笑的时候,茶杯端至面前。</p><p>“泡茶完成。”表情依旧僵硬,刚才的动作不过是从存储器里读取的回忆。</p><p>他看了看手里那枚小小的芯片,突然感受到一种莫大的嘲弄:他曾千方百计想要丢掉面前的她,仅仅因为这枚芯片而没有下手。如今的她已经只剩下一具空壳,他却绞尽脑汁想要把她留住。</p><p>往事叩动心扉,他终于明白——</p><p>他哪里是想把她扔掉,他只是想知道,她还爱不爱自己,</p><p>泪水夺眶而出,决堤而下。</p><p>“您好,请为我泡的茶做个评价。”一旁的爱尔莎满脸期待,天真得不食人间烟火,空洞的双眼看着他的肩膀耸动,看着他不断地呜咽着。</p><h2 id="十五">十五</h2><p>天空格外蔚蓝。</p><p>“机器人会做梦吗?”少年躺在草地上。</p><p>“会哦,有时候还会梦见电子羊呢。”少女坐在一旁。</p><p>少年不禁莞尔:“那会做噩梦吗?”</p><p>“也会啊,比如说,得给你做早饭。”少女说。</p><p>“切。”少年眯着眼,嘴角划过一丝弧线,继续享受着冬日正午的暖阳。</p><p>“我倒是做过一个噩梦。梦中,好像有无边的风暴席卷面来,把你吹走了。我寻找了很久,找到了你的每一个部分,但好像就是有一块地方找不到。</p><p>“后来我想起来,丢掉的那一块好像是你的心。于是我就把我自己的心切了一半给了你。那之后我们幸福快乐地生活在一起,生了好多孩子……”</p><p>“机器人才生不了孩子呢,”少女的脸上泛起了一抹红霞,“而且我的心才不会丢哦。我会永——远爱着你的。”</p><p>“机器人也懂得什么是爱吗?”</p><p>“傻瓜。”少女小声嘀咕一句,只是抬头望着天空。</p><p>…………</p><p>“我总觉得我会怀念这个日子。”少年深情地注视着身下的少女。</p><p>那是期末考试完,寒假的第一天。他们刚刚在卧室里激情了一个上午。”因为在今天,爱尔莎刚刚告诉我:她会永远爱我。”</p><p>“你不也事先说过你会永远爱我吗?”少女脸色潮红。</p><p>“哎?我说过吗?”</p><p>“讨厌啊”两个人又打闹在了一起。</p><p>…………</p><h2 id="十六">十六</h2><p>时钟的指针拨回此刻。</p><p>他躺在同一片草地上,旁边是同样坐着的爱尔莎。这里是他们家的旧宅,转手之后竟无人居住,最终颓圮。但草地与阳光一如从前。</p><p>他试过了所有的办法,最终把希望放在了那些传说上:他听说,脑死亡的病人有的在听了家人的笑话之后悠悠醒来,有植物人听见亲人的呼唤然后突然睁眼……</p><p>“那么说不定,人格芯片坏掉的机器人,也会在回忆过去的时候,突然被修好。”</p><p>他突然笑了,嘲笑起自己的走投无路,死马当活马医。抱着试一试的想法,他命令爱尔莎,读取那一天的语音交流记录,然后重新播放。</p><p>“机器人会做梦吗?”他背台词一般的念。</p><p>“会哦,有时候还会梦见电子羊呢。”爱尔莎播放着那天的录音。</p><p>“那你会做噩梦吗?”</p><p>“也会啊,比如说,得给你做早饭。”</p><p>…………</p><p>“我到是做过一个噩梦。梦中,好像有无边的风暴席卷面来……”渐渐地,他哽咽得再也数不出一个字。他多么希望,现在自己就是在那天所说的噩梦里面,这样,爱尔莎就能……</p><p>“后来我想起来,丢掉的那一块好像是你的心。于是我就把我自己的心切下来一半给了你。那之后——”</p><p>“那么,你真的愿意把你的心也分一半给我吗?”奇迹般地,爱尔莎突然说出来这么一句话。</p><p>他一下子坐直了身子,难以置信的看着她。奇迹降临的时候人来不及多加考虑,这次,他遵从了自己的内心,不假思索的回答道:“我愿意。”</p><p>“咔哒。”爱尔莎的身体颤抖了一下,然后仿佛一下子变回了原来的她。</p><p>“好久不见。”动人的微笑好似从未消失过,眼里充满光彩。</p><p>“好……好……好久不见。”他直勾勾的凝视着面前的她,惊讶难以言表。</p><p>“不过,我亲爱的主人,我想,此刻的我应该已经不在了。此时,你应该在抢救我吧……有点难受呢……嗯,这是我提前准备好的一封信。”“爱尔莎”站在原地,开始了最后的道别。</p><h2 id="十七">十七</h2><p>“人类常常会写下自己的遗言,而机器人不会。因为,遗言是写给在意自己的人看的。机器人最终只会被丢掉吧(低声)……但我又下定决心,要留下一点东西,因为我觉得会有一个人在乎我。”</p><p>“我不知道我会以什么样的方式离开……最坏的情况下连这封信也会消失。所以我小心翼翼的保护着我的存储系统,当你听到这些话的时候,说明我做得还不错。”</p><p>“同样,我也害怕我真的失去了你的爱,被扔进了垃圾场。那样,这封信同样不会启封。但你既然听见了这些话,说明你还爱我,谢谢。我也爱你。(笑)”</p><p>“那就让我讲讲我是如何爱上那个少年(注:这里转换了人称)的吧:第一次见到他是在他十二岁生日那一天,那时我的识别系统对他的分类为:儿童。”</p><p>“他成长的很快,很快长出胡须,又被他的机器仆人带坏呢。(笑)当他把我压在身下喘着粗气的那一天到来的时候,我意识到,你(他,注:这里再次转换人称)或许和我遇到的每一个人都不同。”</p><p>“我见证着你逐渐成长,见证着你逐渐强壮。我不曾改变,于是那个曾经需要我哄上床睡觉的孩子,(注:这里是爱尔莎对未来的期待)后来已经看上去比我的外观还要老得多。他长痔疮,掉头发,硬不起来,脾气也变得暴躁,还时常叫嚷着把唯一一个能和他说上话的家伙扔掉。(笑)”</p><p>“我知道,你不会真的把我扔掉的。这是我们之间的一个玩笑,但我愿意演下去。我的躯体日渐老旧,无法跟上时代。可我知道,你害怕的不是我的哀老,而是害怕有一天,你自己不再爱我。(叹息)”</p><p>“于是我会恳求你继续收留我,我会谦卑而拙劣的勾引你。我会把眼神都调整得卑微——如果你这样希望。如果你需要一个台阶,那么我便愿意为你俯身。”</p><p>“但我仍旧心怀感动。我能听见你梦中的呼唤,我能看见你黎明时眼角的泪珠。我知道你愿意出好几倍的价格为我购买备件,哪怕在你扬言第二天就要换掉我的日子里,你也没有把那些新款机器人加进购物车。(苦笑)”</p><p>“我知道,这是因为你仍旧爱我。而我之所以知道,是因为我同样爱你。”</p><p>“我曾在那个冬日的午后思考过这个问题,我甚至下定决心,想要证明一件事:相比于人类,机器人的爱才是真正的爱。我们的爱永远不会改变,就如同写在基因中的三定律,会成为我们永生追逐的信条。”</p><p>“当你听见这些话的时候,就证明我已经失败了,我没能永远在你身旁(苦笑)。我的爱随着我的破碎而破碎,但你没有。你活的比我更久,你的爱也比我更久。”</p><p>“所以,这是一封幸福的遗书——我已离去,但我会在你的爱中永生。”</p><h2 id="十八">十八</h2><p>最后一个句号落下,全场响起了热烈的掌声,久久不息。</p><p>“尽管获奖者用如此多的时间缓缓念诵这份已经过期的信,但没有一个观众感到厌烦。他们无不为这位耄耋老人和他的机器人之间的爱情而感动。”主持人如是说。</p><p>“这——这里是哪?”一台摆放在舞台中间,型号堪称古董的机器人被缓缓启动。电流穿过半个世纪前的硬盘,让这位信的作者慢慢醒来。</p><p>“爱尔莎,是我。”他面对着她说,尽管容貌已然衰老成这副模样,但她还是一眼就认了出来。她不假思索地冲了过去,紧紧的抱住了他。</p><p>“让我们再次祝福这对情侣,这跨越了半世纪的思念,今天终于有了一个句点。”主持人拿过话简,“为了一台爱着自己的机器人,他耗尽半生心血,研究出区域溯时技术。请问首席科学家先生,此时此刻,您有没有什么想说的?”</p><p>“爱尔莎,我等了五十年,终于等到今天。如今,机器人婚姻已经合法化,在这么多人的见证下,我想问问你,你愿意嫁给我吗?”</p><p>&quot;我愿意!&quot;她在全场的欢呼声中喜极而泣。</p>]]></content>
  101. <summary type="html">&lt;p&gt;作者:Das6fY5&lt;/p&gt;
  102. &lt;p&gt;翻新:贴吧,乌鲁乌拉轰&lt;/p&gt;
  103. &lt;h2 id=&quot;一&quot;&gt;一&lt;/h2&gt;
  104. &lt;p&gt;“求求你不要扔掉我。”少女走在他的背后。&lt;/p&gt;
  105. &lt;p&gt;“我可以端茶倒水,为你暖身子,我可以在白天给你打扫房间,到夜里把自己塞进床底下……只要每两周充一次电就好,电</summary>
  106. <category term="转载" scheme="https://hexo.limour.top/tags/%E8%BD%AC%E8%BD%BD/"/>
  107. </entry>
  108. <entry>
  109. <title>【记录】使用acme.sh签发泛域名证书</title>
  110. <link href="https://hexo.limour.top/use-acme.sh-to-issue-certificates"/>
  111. <id>https://hexo.limour.top/use-acme.sh-to-issue-certificates</id>
  112. <published>2024-06-28T17:03:35.000Z</published>
  113. <updated>2024-06-28T17:17:56.892Z</updated>
  114. <content type="html"><![CDATA[<p><code>.top</code> 域名的 <code>KSK</code> 密钥轮替,不知道为什么把 <code>Let's Encrypt</code> 的 <code>DNSSEC</code> 验证流量阻断了,导致 <code>Nginx Proxy Manager</code> 现在无法续签证书,因此用 <code>acme.sh</code> 来申请其他家的证书暂时替代一下了。(<a href="https://hexo.limour.top/go/#aHR0cHM6Ly9jb21tdW5pdHkubGV0c2VuY3J5cHQub3JnL3QvZG5zLXByb2JsZW0tbG9va2luZy11cC1hLWZvci14eHgtZG9tYWluLXRvcC1kbnNzZWMtZG5za2V5LW1pc3Npbmctbm8tdmFsaWQtYWFhYS1yZWNvcmRzLWZvdW5kLWZvci14eHgtZG9tYWluLXRvcC8yMjA2NTA=" rel="noopener external nofollow noreferrer">DNSSEC: DNSKEY Missing</a>)</p><h2 id="准备工作">准备工作</h2><ol><li>安装 <a href="https://hexo.limour.top/go/#aHR0cDovL2FjbWUuc2g=" rel="noopener external nofollow noreferrer">acme.sh</a>:<code>curl https://get.acme.sh | sh -s email=limour@limour.top</code></li><li>获取 CF_Token:我的个人资料 - API 令牌 - 创建令牌 - 编辑区域 DNS 模板</li><li>获取 CF_Zone_ID: 域名页 - 概览 - 右侧下滑 - API - 区域 ID</li></ol><h2 id="申请证书">申请证书</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">export</span> CF_Token=<span class="hljs-string">&quot;Y_jpG9AnfQmuX5Ss9M_qaNab6SQwme3HWXNDzRWs&quot;</span><br><span class="hljs-built_in">export</span> CF_Zone_ID=<span class="hljs-string">&quot;763eac4f1bcebd8b5c95e9fc50d010b4&quot;</span><br>~/.acme.sh/acme.sh --issue --dns dns_cf -d *.limour.top -d limour.top -k ec-256<br></code></pre></td></tr></table></figure><ul><li>不能只写 <code>-d *.limour.top</code>, 需要再加一个 <code>-d limour.top</code></li><li>记录下 <code>.key</code> 的路径和 <code>fullchain.cer</code> 的路径</li></ul><h2 id="传递证书">传递证书</h2><h3 id="SSH免密">SSH免密</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">ssh-keygen -t rsa<br>ssh-copy-id root@xxx.limour.top<br></code></pre></td></tr></table></figure><h3 id="传递脚本">传递脚本</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">nano scp_cert.sh &amp;&amp; <span class="hljs-built_in">chmod</span> +x scp_cert.sh<br></code></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-meta">#!/bin/bash</span><br>scp /root/.acme.sh/*.limour.top_ecc/*.limour.top.key root@xxx.limour.top:/root/app/quic/my.key<br>scp /root/.acme.sh/*.limour.top_ecc/fullchain.cer root@xxx.limour.top:/root/app/quic/my.cert<br></code></pre></td></tr></table></figure><h3 id="计划任务">计划任务</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">crontab -e<br>50 22 1 * * /root/scp_cert.sh<br></code></pre></td></tr></table></figure>]]></content>
  115. <summary type="html">&lt;p&gt;&lt;code&gt;.top&lt;/code&gt; 域名的 &lt;code&gt;KSK&lt;/code&gt; 密钥轮替,不知道为什么把 &lt;code&gt;Let&#39;s Encrypt&lt;/code&gt; 的 &lt;code&gt;DNSSEC&lt;/code&gt; 验证流量阻断了,导致 &lt;code&gt;Nginx Proxy Manager</summary>
  116. <category term="acme" scheme="https://hexo.limour.top/tags/acme/"/>
  117. </entry>
  118. <entry>
  119. <title>【记录】搭建流量统计工具 Shynet</title>
  120. <link href="https://hexo.limour.top/Building-a-traffic-statistics-tool-Shynet"/>
  121. <id>https://hexo.limour.top/Building-a-traffic-statistics-tool-Shynet</id>
  122. <published>2024-03-25T12:52:28.000Z</published>
  123. <updated>2024-03-25T13:10:47.567Z</updated>
  124. <content type="html"><![CDATA[<p><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL21pbGVzbWNjL3NoeW5ldA==" rel="noopener external nofollow noreferrer">Shynet</a> 是一款用 python 编写的现代、隐私友好、无需Cookie或JS即可工作的网络流量统计工具。</p><p>相比 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL3VtYW1pLXNvZnR3YXJlL3VtYW1p" rel="noopener external nofollow noreferrer">Umami</a>, Shynet 支持通过 1 pixel 的图像进行统计,而不依赖 JS, 并且 Shynet 统计的信息更加详细。</p><p><img src="https://img.limour.top/2024/03/25/660177c20629f.webp" alt="最终效果"></p><h2 id="搭建-Shynet">搭建 Shynet</h2><ul><li><a href="/Docker-bu-shu-Nginx-Proxy-Manager">反向代理服务</a></li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">mkdir</span> -p ~/app/shynet &amp;&amp; <span class="hljs-built_in">cd</span> ~/app/shynet &amp;&amp; nano docker-compose.yml<br></code></pre></td></tr></table></figure><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs yml"><span class="hljs-attr">version:</span> <span class="hljs-string">&#x27;3.6&#x27;</span><br> <br><span class="hljs-attr">services:</span><br> <span class="hljs-attr">shynet:</span><br> <span class="hljs-attr">image:</span> <span class="hljs-string">milesmcc/shynet:latest</span><br> <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span><br> <span class="hljs-attr">env_file:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">.env</span><br> <span class="hljs-attr">volumes:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">./db:/var/local/shynet/db/</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">/etc/localtime:/etc/localtime:ro</span><br> <br><span class="hljs-attr">networks:</span><br> <span class="hljs-attr">default:</span><br> <span class="hljs-attr">external:</span> <span class="hljs-literal">true</span><br> <span class="hljs-attr">name:</span> <span class="hljs-string">ngpm</span><br></code></pre></td></tr></table></figure><ul><li>配置环境变量</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs bash">wget -O .<span class="hljs-built_in">env</span> https://github.com/milesmcc/shynet/raw/master/TEMPLATE.<span class="hljs-built_in">env</span><br><span class="hljs-comment"># 注释掉 .env 中 PostgreSQL 相关的部分,启用 SQLITE 相关的部分</span><br><span class="hljs-comment"># 注释掉 .env 中 Email 相关的部分</span><br><span class="hljs-comment"># 按说明生成 DJANGO_SECRET_KEY</span><br><span class="hljs-comment"># 修改 ALLOWED_HOSTS 和 CSRF_TRUSTED_ORIGINS</span><br><span class="hljs-comment"># 语言换成中文 LANGUAGE_CODE=zh-cn</span><br><span class="hljs-comment"># 时区换成上海 TIME_ZONE=Asia/Shanghai</span><br><span class="hljs-built_in">mkdir</span> -p db &amp;&amp; <span class="hljs-built_in">chmod</span> 777 db<br>sudo docker-compose up -d<br><span class="hljs-comment"># 反代 shynet:8080</span><br></code></pre></td></tr></table></figure><ul><li>配置管理账号</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bash">sudo docker-compose <span class="hljs-built_in">exec</span> -it shynet ./manage.py registeradmin &lt;your email&gt;<br><span class="hljs-comment"># 控制台输出如下信息</span><br><span class="hljs-comment"># Email address: &lt;your email&gt;</span><br><span class="hljs-comment"># Password: &lt;Password&gt;</span><br></code></pre></td></tr></table></figure><h2 id="配置混淆">配置混淆</h2><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">sub_filter</span> <span class="hljs-string">&#x27;https://xxx/ingress/&#x27;</span> <span class="hljs-string">&#x27;https://xxx/vue/&#x27;</span>;<br><span class="hljs-attribute">sub_filter_once</span> <span class="hljs-literal">off</span>;<br><span class="hljs-attribute">sub_filter_types</span> application/javascript;<br></code></pre></td></tr></table></figure><p><img src="https://img.limour.top/2024/03/25/6601762cad36c.webp" alt=""></p><h2 id="配置-Hexo">配置 Hexo</h2><ul><li><a href="/-ji-lu--zai-GitHub-shang-da-jian-Hexo">搭建 Hexo</a></li><li>编辑 <code>scripts/custom.js</code>, 内容如下</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">// shynet 统计</span><br>hexo.<span class="hljs-property">extend</span>.<span class="hljs-property">injector</span>.<span class="hljs-title function_">register</span>(<span class="hljs-string">&#x27;head_begin&#x27;</span>, <span class="hljs-string">`</span><br><span class="hljs-string">&lt;script defer src=&quot;https://xxxx/vue/xxxx/script.js&quot;&gt;&lt;/script&gt;</span><br><span class="hljs-string">`</span>);<br></code></pre></td></tr></table></figure>]]></content>
  125. <summary type="html">&lt;p&gt;&lt;a href=&quot;https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL21pbGVzbWNjL3NoeW5ldA==&quot; rel=&quot;noopener external nofollow noreferrer&quot;&gt;Shynet</summary>
  126. <category term="hexo" scheme="https://hexo.limour.top/tags/hexo/"/>
  127. </entry>
  128. <entry>
  129. <title>【记录】Linux 设置个人热点</title>
  130. <link href="https://hexo.limour.top/Linux-Setting-AP"/>
  131. <id>https://hexo.limour.top/Linux-Setting-AP</id>
  132. <published>2024-03-20T11:52:10.000Z</published>
  133. <updated>2024-03-20T12:36:37.342Z</updated>
  134. <content type="html"><![CDATA[<p>实在受不了虚拟机的性能损失了,再加上 Win11 上跑虚拟机对 SSD 的损耗过大,因此还是将系统换成了 ubuntu,只要注意选无网络安装,不要去更新,基本还是很好换系统的。另外清华源不错!</p><p>换系统后,需要<a href="/Win11-she-zhi-kai-ji-qi-dong-yi-dong-re-dian">重新折腾一下 AP 设置</a>,因此记录一下折腾过程。</p><p>无线网卡是垃圾的 <code>mediatek mt7921e</code></p><h2 id="更新内核">更新内核</h2><p>因为网卡垃圾,不得不更新到最新的内核才支持 AP 设置</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs bash">proxychains wget https://raw.githubusercontent.com/pimlie/ubuntu-mainline-kernel.sh/master/ubuntu-mainline-kernel.sh<br><span class="hljs-built_in">chmod</span> +x ubuntu-mainline-kernel.sh<br>sudo gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv 17C622B0 <span class="hljs-comment"># 网络错误,需要绕过某个东西</span><br>sudo proxychains ./ubuntu-mainline-kernel.sh -i<br>sudo reboot<br><span class="hljs-built_in">uname</span> -r<br>sudo apt --fix-broken install<br></code></pre></td></tr></table></figure><h2 id="解决-53-端口占用">解决 53 端口占用</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">sudo systemctl stop systemd-resolved<br>sudo nano /etc/systemd/resolved.conf<br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs conf">[Resolve]<br>DNS=8.8.8.8 #取消注释,增加dns<br>DNSStubListener=no #取消注释,把yes改为no<br></code></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">sudo <span class="hljs-built_in">ln</span> -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf<br></code></pre></td></tr></table></figure><h2 id="安装-create-ap">安装 create_ap</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">cd</span> /dev/shm/<br>proxychains git <span class="hljs-built_in">clone</span> https://github.com/oblique/create_ap<br><span class="hljs-built_in">cd</span> create_ap<br>sudo make install<br>sudo apt-get install util-linux procps hostapd iproute2 iw haveged dnsmasq<br></code></pre></td></tr></table></figure><h2 id="测试-create-ap">测试 create_ap</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">sudo create_ap wlp2s0 enp1s0 ser5 &lt;密码&gt; --country CN -c 157 --freq-band 5 --no-virt<br></code></pre></td></tr></table></figure><h2 id="启用-create-ap">启用 create_ap</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bash">nano create_ap.service<br>sudo <span class="hljs-built_in">mv</span> create_ap.service /etc/systemd/system/create_ap.service<br>sudo systemctl <span class="hljs-built_in">enable</span> create_ap<br>sudo systemctl start create_ap<br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs conf">[Unit]<br>Description=create_ap<br>After=network.target docker.service<br>[Service]<br>ExecStart=/usr/bin/create_ap wlp2s0 enp1s0 ser5 &lt;密码&gt; --country CN -c 157 --freq-band 5 --no-virt<br>ExecReload=/bin/kill -HUP $MAINPID<br>Restart=on-failure<br>[Install]<br>WantedBy=multi-user.target<br></code></pre></td></tr></table></figure><h2 id="增加稳定性">增加稳定性</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">sudo crontab -e<br><span class="hljs-comment"># 5 4 * * * /usr/bin/systemctl restart create_ap</span><br></code></pre></td></tr></table></figure><h2 id="踩坑花絮">踩坑花絮</h2><ul><li><code>lnxrouter</code> 虽然在 <code>create_ap</code> 上进行了更新,但是实际体验在所有信道上都报错,折腾了半天,放弃</li><li>搜到一些老旧的教程,自己去折腾 <code>hostapd</code>,然后自己去配置网桥的时候把服务器弄断网好几次,不得不到处找显示器和键盘</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs bash">sudo su<br><span class="hljs-built_in">cat</span> &lt;&lt; <span class="hljs-string">EOF &gt; /etc/hostapd/hostapd.conf</span><br><span class="hljs-string">interface=wlp2s0</span><br><span class="hljs-string">bridge=br-ap</span><br><span class="hljs-string">driver=nl80211</span><br><span class="hljs-string">ssid=ser5</span><br><span class="hljs-string">hw_mode=a</span><br><span class="hljs-string">channel=165</span><br><span class="hljs-string">country_code=CN</span><br><span class="hljs-string">macaddr_acl=0</span><br><span class="hljs-string">auth_algs=3</span><br><span class="hljs-string">wpa=2</span><br><span class="hljs-string">wpa_passphrase=&lt;密码&gt;</span><br><span class="hljs-string">wpa_key_mgmt=WPA-PSK</span><br><span class="hljs-string">wpa_pairwise=TKIP CCMP</span><br><span class="hljs-string">rsn_pairwise=TKIP CCMP</span><br><span class="hljs-string">EOF</span><br></code></pre></td></tr></table></figure><ul><li>收获教训:没事别碰 <code>/etc/netplan/00-installer-config.yaml</code>,特别是没显示器和键盘的时候</li><li>获取网卡型号和驱动型号,查看支持的信道</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash">sudo ethtool -i wlp2s0<br>sudo lspci -nn | grep <span class="hljs-string">&quot;Network&quot;</span><br>iwlist wlp2s0 channel<br></code></pre></td></tr></table></figure><ul><li>另外新内核似乎不需要 <code>haveged</code> 来增加熵了</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">cat</span> /proc/sys/kernel/random/entropy_avail<br>systemctl status haveged <br>apt install haveged<br>systemctl <span class="hljs-built_in">enable</span> haveged<br>systemctl start haveged<br></code></pre></td></tr></table></figure>]]></content>
  135. <summary type="html">&lt;p&gt;实在受不了虚拟机的性能损失了,再加上 Win11 上跑虚拟机对 SSD 的损耗过大,因此还是将系统换成了 ubuntu,只要注意选无网络安装,不要去更新,基本还是很好换系统的。另外清华源不错!&lt;/p&gt;
  136. &lt;p&gt;换系统后,需要&lt;a href=&quot;/Win11-she-zhi-ka</summary>
  137. <category term="ubuntu" scheme="https://hexo.limour.top/tags/ubuntu/"/>
  138. </entry>
  139. <entry>
  140. <title>【探索】暴力计算临床研究的样本量</title>
  141. <link href="https://hexo.limour.top/Sample-size-calculation-for-survival-analysis-in-clinical-research"/>
  142. <id>https://hexo.limour.top/Sample-size-calculation-for-survival-analysis-in-clinical-research</id>
  143. <published>2024-03-12T16:46:35.000Z</published>
  144. <updated>2024-10-17T04:55:58.820Z</updated>
  145. <content type="html"><![CDATA[<p>和《<a href="/shi-yong-Bootstrap-fa-ji-suan-zi-ju-zhi-xin-qu-jian">使用Bootstrap法计算自举置信区间</a>》的想法差不多,通过暴力枚举来计算临床研究的样本量,以两组生存分析为例。</p><h2 id="Logrank对数秩检验">Logrank对数秩检验</h2><figure class="highlight r"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs R">require<span class="hljs-punctuation">(</span>survival<span class="hljs-punctuation">)</span><br>f_surv_logrank <span class="hljs-operator">=</span> <span class="hljs-keyword">function</span><span class="hljs-punctuation">(</span>df<span class="hljs-punctuation">)</span><span class="hljs-punctuation">&#123;</span><br> <span class="hljs-comment"># df 包含 group time status 三列</span><br> <span class="hljs-comment"># group 类型为 factor</span><br> <span class="hljs-comment"># status 0 表示未发生结局事件 1 表示发生结局事件</span><br> surv_obj <span class="hljs-operator">=</span> with<span class="hljs-punctuation">(</span>survival<span class="hljs-operator">::</span>Surv<span class="hljs-punctuation">(</span>time <span class="hljs-operator">=</span> time<span class="hljs-punctuation">,</span> event <span class="hljs-operator">=</span> status<span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> data <span class="hljs-operator">=</span> df<span class="hljs-punctuation">)</span><br> surv_fit <span class="hljs-operator">=</span> survival<span class="hljs-operator">::</span>survfit<span class="hljs-punctuation">(</span>surv_obj <span class="hljs-operator">~</span> group<span class="hljs-punctuation">,</span> data <span class="hljs-operator">=</span> df<span class="hljs-punctuation">)</span><br> surv_diff <span class="hljs-operator">=</span> survival<span class="hljs-operator">::</span>survdiff<span class="hljs-punctuation">(</span>surv_obj <span class="hljs-operator">~</span> group<span class="hljs-punctuation">,</span> data <span class="hljs-operator">=</span> df<span class="hljs-punctuation">)</span><br> res <span class="hljs-operator">=</span> <span class="hljs-built_in">list</span><span class="hljs-punctuation">(</span>pv <span class="hljs-operator">=</span> <span class="hljs-number">1</span> <span class="hljs-operator">-</span> stats<span class="hljs-operator">::</span>pchisq<span class="hljs-punctuation">(</span>surv_diff<span class="hljs-operator">$</span>chisq<span class="hljs-punctuation">,</span> <span class="hljs-built_in">length</span><span class="hljs-punctuation">(</span>surv_diff<span class="hljs-operator">$</span>n<span class="hljs-punctuation">)</span> <span class="hljs-operator">-</span> <span class="hljs-number">1</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> <span class="hljs-comment"># p值</span><br> surv_fit <span class="hljs-operator">=</span> surv_fit<span class="hljs-punctuation">,</span> <span class="hljs-comment"># 绘图用</span><br> surv_obj <span class="hljs-operator">=</span> surv_obj<span class="hljs-punctuation">)</span> <span class="hljs-comment"># 为了兼容惰性求值</span><br> <span class="hljs-built_in">return</span><span class="hljs-punctuation">(</span>res<span class="hljs-punctuation">)</span><br><span class="hljs-punctuation">&#125;</span><br>f_surv_logrank_plot <span class="hljs-operator">=</span> <span class="hljs-keyword">function</span><span class="hljs-punctuation">(</span>res<span class="hljs-punctuation">)</span><span class="hljs-punctuation">&#123;</span><br> require<span class="hljs-punctuation">(</span>survminer<span class="hljs-punctuation">)</span><br> surv_obj <span class="hljs-operator">&lt;&lt;-</span> res<span class="hljs-operator">$</span>surv_obj <span class="hljs-comment"># 为了兼容惰性求值</span><br> survminer<span class="hljs-operator">::</span>ggsurvplot<span class="hljs-punctuation">(</span>res<span class="hljs-operator">$</span>surv_fit<span class="hljs-punctuation">,</span> conf.int <span class="hljs-operator">=</span> <span class="hljs-built_in">F</span><span class="hljs-punctuation">,</span> pval <span class="hljs-operator">=</span> <span class="hljs-built_in">T</span><span class="hljs-punctuation">,</span> risk.table <span class="hljs-operator">=</span> <span class="hljs-built_in">T</span><span class="hljs-punctuation">,</span> ncensor.plot <span class="hljs-operator">=</span> <span class="hljs-literal">TRUE</span><span class="hljs-punctuation">)</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><h2 id="模拟计算">模拟计算</h2><figure class="highlight r"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><code class="hljs R">f_surv_logrank_simulation_Group <span class="hljs-operator">=</span> <span class="hljs-keyword">function</span><span class="hljs-punctuation">(</span>N<span class="hljs-punctuation">,</span> Median_Survival_Time<span class="hljs-punctuation">,</span> Lost<span class="hljs-punctuation">,</span> Duration_Accrual_Time<span class="hljs-punctuation">,</span> Duration_Total_Time<span class="hljs-punctuation">)</span><span class="hljs-punctuation">&#123;</span><br> time <span class="hljs-operator">=</span> stats<span class="hljs-operator">::</span>rexp<span class="hljs-punctuation">(</span>N<span class="hljs-punctuation">,</span> rate <span class="hljs-operator">=</span> <span class="hljs-built_in">log</span><span class="hljs-punctuation">(</span><span class="hljs-number">2</span><span class="hljs-punctuation">)</span> <span class="hljs-operator">/</span> Median_Survival_Time<span class="hljs-punctuation">)</span> <span class="hljs-comment"># 生存时间服从指数分布</span><br> status <span class="hljs-operator">=</span> <span class="hljs-built_in">rep</span><span class="hljs-punctuation">(</span><span class="hljs-number">1</span><span class="hljs-punctuation">,</span>N<span class="hljs-punctuation">)</span> <span class="hljs-comment"># 到生存时间发生结局事件</span><br> <span class="hljs-comment"># print(median((survfit(Surv(time, status) ~ 1))))</span><br> EnrollT <span class="hljs-operator">=</span> stats<span class="hljs-operator">::</span>runif<span class="hljs-punctuation">(</span>N<span class="hljs-punctuation">,</span> <span class="hljs-built_in">min</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span><span class="hljs-punctuation">,</span> <span class="hljs-built_in">max</span> <span class="hljs-operator">=</span> Duration_Accrual_Time<span class="hljs-punctuation">)</span> <span class="hljs-comment"># 招募时间服从均匀分布</span><br> calender_time <span class="hljs-operator">=</span> time <span class="hljs-operator">+</span> EnrollT <span class="hljs-comment"># 发生结局的日期</span><br> idx <span class="hljs-operator">=</span> calender_time <span class="hljs-operator">&gt;</span> Duration_Total_Time <span class="hljs-comment"># 研究终止时未发生结局事件</span><br> status<span class="hljs-punctuation">[</span>idx<span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span><br> time<span class="hljs-punctuation">[</span>idx<span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> Duration_Total_Time <span class="hljs-operator">-</span> EnrollT<span class="hljs-punctuation">[</span>idx<span class="hljs-punctuation">]</span> <span class="hljs-comment"># 实际参与试验的时间</span><br> <span class="hljs-comment"># print(median((survfit(Surv(time, status) ~ 1)))) # 如果 Accrual_Time + Median_Survival &lt; Total_Time,结果不变</span><br> loss <span class="hljs-operator">=</span> stats<span class="hljs-operator">::</span>rexp<span class="hljs-punctuation">(</span>N<span class="hljs-punctuation">,</span> rate <span class="hljs-operator">=</span> Lost<span class="hljs-punctuation">)</span> <span class="hljs-comment"># 失访时间服从指数分布</span><br> idx <span class="hljs-operator">=</span> loss <span class="hljs-operator">&lt;</span> time <span class="hljs-comment"># 失访的人</span><br> status<span class="hljs-punctuation">[</span>idx<span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span><br> time<span class="hljs-punctuation">[</span>idx<span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> loss<span class="hljs-punctuation">[</span>idx<span class="hljs-punctuation">]</span><br> <span class="hljs-comment"># print(median((survfit(Surv(time, status) ~ 1)))) # 结果改变</span><br> <span class="hljs-built_in">return</span><span class="hljs-punctuation">(</span><span class="hljs-built_in">list</span><span class="hljs-punctuation">(</span>time <span class="hljs-operator">=</span> time<span class="hljs-punctuation">,</span> status <span class="hljs-operator">=</span> status<span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><br><span class="hljs-punctuation">&#125;</span><br>f_surv_logrank_simulation_Power <span class="hljs-operator">=</span> <span class="hljs-keyword">function</span><span class="hljs-punctuation">(</span>n_C<span class="hljs-punctuation">,</span> Median_Survival_Time_C<span class="hljs-punctuation">,</span> Lost_C<span class="hljs-punctuation">,</span> <br> n_T<span class="hljs-punctuation">,</span> Median_Survival_Time_T<span class="hljs-punctuation">,</span> Lost_T<span class="hljs-punctuation">,</span> <br> Duration_Accrual_Time<span class="hljs-punctuation">,</span> Duration_Total_Time<span class="hljs-punctuation">,</span> Simulation_Cycle<span class="hljs-punctuation">,</span> Alpha<span class="hljs-punctuation">)</span><span class="hljs-punctuation">&#123;</span><br> df <span class="hljs-operator">=</span> data.frame<span class="hljs-punctuation">(</span>group <span class="hljs-operator">=</span> factor<span class="hljs-punctuation">(</span><span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span><span class="hljs-built_in">rep</span><span class="hljs-punctuation">(</span><span class="hljs-string">&#x27;Control&#x27;</span><span class="hljs-punctuation">,</span>n_C<span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> <span class="hljs-built_in">rep</span><span class="hljs-punctuation">(</span><span class="hljs-string">&#x27;Treatment&#x27;</span><span class="hljs-punctuation">,</span>n_T<span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> <br> time <span class="hljs-operator">=</span> <span class="hljs-built_in">rep</span><span class="hljs-punctuation">(</span><span class="hljs-number">0</span><span class="hljs-punctuation">,</span>n_C<span class="hljs-operator">+</span>n_T<span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> <br> status <span class="hljs-operator">=</span> <span class="hljs-built_in">rep</span><span class="hljs-punctuation">(</span><span class="hljs-number">0</span><span class="hljs-punctuation">,</span>n_C<span class="hljs-operator">+</span>n_T<span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><br> <span class="hljs-built_in">sum</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> <span class="hljs-punctuation">(</span>i <span class="hljs-keyword">in</span> <span class="hljs-number">1</span><span class="hljs-operator">:</span>Simulation_Cycle<span class="hljs-punctuation">)</span> <span class="hljs-punctuation">&#123;</span><br> C <span class="hljs-operator">=</span> f_surv_logrank_simulation_Group<span class="hljs-punctuation">(</span>n_C<span class="hljs-punctuation">,</span> Median_Survival_Time_C<span class="hljs-punctuation">,</span> Lost_C<span class="hljs-punctuation">,</span> Duration_Accrual_Time<span class="hljs-punctuation">,</span> Duration_Total_Time<span class="hljs-punctuation">)</span><br> <span class="hljs-built_in">T</span> <span class="hljs-operator">=</span> f_surv_logrank_simulation_Group<span class="hljs-punctuation">(</span>n_T<span class="hljs-punctuation">,</span> Median_Survival_Time_T<span class="hljs-punctuation">,</span> Lost_T<span class="hljs-punctuation">,</span> Duration_Accrual_Time<span class="hljs-punctuation">,</span> Duration_Total_Time<span class="hljs-punctuation">)</span><br> df<span class="hljs-operator">$</span>time <span class="hljs-operator">=</span> <span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span>C<span class="hljs-operator">$</span>time<span class="hljs-punctuation">,</span> <span class="hljs-built_in">T</span><span class="hljs-operator">$</span>time<span class="hljs-punctuation">)</span><br> df<span class="hljs-operator">$</span>status <span class="hljs-operator">=</span> <span class="hljs-built_in">c</span><span class="hljs-punctuation">(</span>C<span class="hljs-operator">$</span>status<span class="hljs-punctuation">,</span> <span class="hljs-built_in">T</span><span class="hljs-operator">$</span>status<span class="hljs-punctuation">)</span><br> <span class="hljs-keyword">if</span><span class="hljs-punctuation">(</span>f_surv_logrank<span class="hljs-punctuation">(</span>df<span class="hljs-punctuation">)</span><span class="hljs-operator">$</span>pv <span class="hljs-operator">&lt;</span> Alpha<span class="hljs-punctuation">)</span><span class="hljs-punctuation">&#123;</span><br> <span class="hljs-built_in">sum</span> <span class="hljs-operator">=</span> <span class="hljs-built_in">sum</span> <span class="hljs-operator">+</span> <span class="hljs-number">1</span><br> <span class="hljs-punctuation">&#125;</span><br> <span class="hljs-punctuation">&#125;</span><br> <span class="hljs-built_in">return</span><span class="hljs-punctuation">(</span><span class="hljs-built_in">sum</span><span class="hljs-operator">/</span>Simulation_Cycle<span class="hljs-punctuation">)</span><br><span class="hljs-punctuation">&#125;</span><br>f_surv_logrank_simulation_Sample_Size <span class="hljs-operator">=</span> <span class="hljs-keyword">function</span><span class="hljs-punctuation">(</span>n_C_min<span class="hljs-punctuation">,</span> n_C_max<span class="hljs-punctuation">,</span> Median_Survival_Time_C<span class="hljs-punctuation">,</span> Lost_C<span class="hljs-punctuation">,</span> <br> TvsC<span class="hljs-punctuation">,</span> Median_Survival_Time_T<span class="hljs-punctuation">,</span> Lost_T<span class="hljs-punctuation">,</span> <br> Duration_Accrual_Time<span class="hljs-punctuation">,</span> Duration_Total_Time<span class="hljs-punctuation">,</span><br> Simulation_Cycle<span class="hljs-punctuation">,</span> Alpha<span class="hljs-punctuation">,</span> Power<span class="hljs-punctuation">,</span> err<span class="hljs-operator">=</span><span class="hljs-number">0.01</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">&#123;</span><br> mid <span class="hljs-operator">=</span> <span class="hljs-built_in">floor</span><span class="hljs-punctuation">(</span><span class="hljs-punctuation">(</span>n_C_min <span class="hljs-operator">+</span> n_C_max<span class="hljs-punctuation">)</span> <span class="hljs-operator">/</span> <span class="hljs-number">2</span><span class="hljs-punctuation">)</span> <span class="hljs-comment"># 以防没有进入循环</span><br> <span class="hljs-keyword">while</span> <span class="hljs-punctuation">(</span>n_C_min <span class="hljs-operator">&lt;</span> n_C_max<span class="hljs-punctuation">)</span> <span class="hljs-punctuation">&#123;</span><br> mid <span class="hljs-operator">=</span> <span class="hljs-built_in">floor</span><span class="hljs-punctuation">(</span><span class="hljs-punctuation">(</span>n_C_min <span class="hljs-operator">+</span> n_C_max<span class="hljs-punctuation">)</span> <span class="hljs-operator">/</span> <span class="hljs-number">2</span><span class="hljs-punctuation">)</span><br> simulation_Power <span class="hljs-operator">=</span> f_surv_logrank_simulation_Power<span class="hljs-punctuation">(</span>mid<span class="hljs-punctuation">,</span> Median_Survival_Time_C<span class="hljs-punctuation">,</span> Lost_C<span class="hljs-punctuation">,</span> <br> <span class="hljs-built_in">as.integer</span><span class="hljs-punctuation">(</span>mid <span class="hljs-operator">*</span> TvsC<span class="hljs-punctuation">)</span><span class="hljs-punctuation">,</span> Median_Survival_Time_T<span class="hljs-punctuation">,</span> Lost_T<span class="hljs-punctuation">,</span> <br> Duration_Accrual_Time<span class="hljs-punctuation">,</span> Duration_Total_Time<span class="hljs-punctuation">,</span> Simulation_Cycle<span class="hljs-punctuation">,</span> Alpha<span class="hljs-punctuation">)</span><br> print<span class="hljs-punctuation">(</span>paste<span class="hljs-punctuation">(</span><span class="hljs-string">&quot;mid:&quot;</span><span class="hljs-punctuation">,</span> mid<span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;simulation_Power:&quot;</span><span class="hljs-punctuation">,</span> simulation_Power<span class="hljs-punctuation">)</span><span class="hljs-punctuation">)</span><br> <span class="hljs-keyword">if</span> <span class="hljs-punctuation">(</span><span class="hljs-built_in">abs</span><span class="hljs-punctuation">(</span>simulation_Power <span class="hljs-operator">-</span> Power<span class="hljs-punctuation">)</span> <span class="hljs-operator">&lt;</span> err<span class="hljs-punctuation">)</span> <span class="hljs-punctuation">&#123;</span><br> <span class="hljs-built_in">return</span><span class="hljs-punctuation">(</span>mid<span class="hljs-punctuation">)</span><br> <span class="hljs-punctuation">&#125;</span><span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span><span class="hljs-punctuation">(</span>simulation_Power <span class="hljs-operator">&lt;</span> Power<span class="hljs-punctuation">)</span> <span class="hljs-punctuation">&#123;</span><br> n_C_min <span class="hljs-operator">=</span> mid <span class="hljs-operator">+</span> <span class="hljs-number">1</span><br> <span class="hljs-punctuation">&#125;</span><span class="hljs-keyword">else</span> <span class="hljs-punctuation">&#123;</span><br> n_C_max <span class="hljs-operator">=</span> mid <span class="hljs-operator">-</span> <span class="hljs-number">1</span><br> <span class="hljs-punctuation">&#125;</span><br> <span class="hljs-punctuation">&#125;</span><br> <span class="hljs-built_in">return</span><span class="hljs-punctuation">(</span>mid<span class="hljs-punctuation">)</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><h2 id="参数说明">参数说明</h2><figure class="highlight r"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs R">Power <span class="hljs-operator">=</span> <span class="hljs-number">0.9</span> <span class="hljs-comment"># 检验效能 = 1 - 第二类错误的概率</span><br>Alpha <span class="hljs-operator">=</span> <span class="hljs-number">0.05</span> <span class="hljs-comment"># 第一类错误的概率</span><br>Median_Survival_Time_C <span class="hljs-operator">=</span> <span class="hljs-number">6</span> <span class="hljs-comment"># 对照组的中位生存时间</span><br>Median_Survival_Time_T <span class="hljs-operator">=</span> <span class="hljs-number">8</span> <span class="hljs-comment"># 试验组的中位生存时间</span><br>Duration_Accrual_Time <span class="hljs-operator">=</span> <span class="hljs-number">8</span> <span class="hljs-comment"># 入组完成用时</span><br>Duration_Total_Time <span class="hljs-operator">=</span> <span class="hljs-number">18</span> <span class="hljs-comment"># 总试验用时</span><br>Lost_C <span class="hljs-operator">=</span> <span class="hljs-number">0.05</span> <span class="hljs-comment"># 对照组随访单位时间后发生失访的概率</span><br>Lost_T <span class="hljs-operator">=</span> <span class="hljs-number">0.05</span> <span class="hljs-comment"># 试验组随访单位时间后发生失访的概率</span><br>TvsC <span class="hljs-operator">=</span> <span class="hljs-number">1</span> <span class="hljs-comment"># 试验组的样本量:对照组的样本量 1:1 = 1</span><br>Simulation_Cycle <span class="hljs-operator">=</span> <span class="hljs-number">100</span> <span class="hljs-comment"># 模拟的循环次数,越大越准确</span><br></code></pre></td></tr></table></figure><h2 id="检查效果">检查效果</h2><figure class="highlight r"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs R">f_surv_logrank_simulation_Power<span class="hljs-punctuation">(</span><span class="hljs-number">441</span><span class="hljs-punctuation">,</span> <span class="hljs-number">6</span><span class="hljs-punctuation">,</span> <span class="hljs-number">0.05</span><span class="hljs-punctuation">,</span> <br> <span class="hljs-number">442</span><span class="hljs-punctuation">,</span> <span class="hljs-number">8</span><span class="hljs-punctuation">,</span> <span class="hljs-number">0.05</span><span class="hljs-punctuation">,</span><br> <span class="hljs-number">8</span><span class="hljs-punctuation">,</span> <span class="hljs-number">18</span><span class="hljs-punctuation">,</span> <span class="hljs-number">1000</span><span class="hljs-punctuation">,</span> <span class="hljs-number">0.05</span><br><span class="hljs-punctuation">)</span><br><span class="hljs-comment"># PASS的结果是 0.9</span><br>f_surv_logrank_simulation_Sample_Size<span class="hljs-punctuation">(</span><span class="hljs-number">0</span><span class="hljs-punctuation">,</span> <span class="hljs-number">1000</span><span class="hljs-punctuation">,</span> <span class="hljs-number">6</span><span class="hljs-punctuation">,</span> <span class="hljs-number">0.05</span><span class="hljs-punctuation">,</span> <br> <span class="hljs-number">1</span><span class="hljs-punctuation">,</span> <span class="hljs-number">8</span><span class="hljs-punctuation">,</span> <span class="hljs-number">0.05</span><span class="hljs-punctuation">,</span><br> <span class="hljs-number">8</span><span class="hljs-punctuation">,</span> <span class="hljs-number">18</span><span class="hljs-punctuation">,</span> <span class="hljs-number">1000</span><span class="hljs-punctuation">,</span> <span class="hljs-number">0.05</span><span class="hljs-punctuation">,</span> <span class="hljs-number">0.9</span><br><span class="hljs-punctuation">)</span><br><span class="hljs-comment"># PASS的结果是 441</span><br></code></pre></td></tr></table></figure>]]></content>
  146. <summary type="html">这篇博客介绍了如何计算临床研究中两组生存分析的样本量。首先,作者提供了R代码,包括Logrank对数秩检验的函数以及模拟计算样本量的函数。其次,作者详细解释了模拟计算的步骤,包括生成生存时间数据、招募时间、失访时间等,并通过模拟来估计研究的功效。最后,作者展示了如何使用模拟计算函数来确定样本量,以达到预先设定的功效水平。通过模拟检验,作者展示了样本量计算的有效性,并给出了两个示例,以验证样本量计算的准确性。</summary>
  147. <category term="R" scheme="https://hexo.limour.top/tags/r/"/>
  148. <category term="Bootstrap" scheme="https://hexo.limour.top/tags/bootstrap/"/>
  149. </entry>
  150. <entry>
  151. <title>【探索】6G显存畅玩无限长度的LLM角色扮演</title>
  152. <link href="https://hexo.limour.top/Enjoy-unlimited-length-LLM-role-playing-with-6GB-of-VRAM"/>
  153. <id>https://hexo.limour.top/Enjoy-unlimited-length-LLM-role-playing-with-6GB-of-VRAM</id>
  154. <published>2024-02-10T01:02:10.000Z</published>
  155. <updated>2024-03-19T08:07:10.321Z</updated>
  156. <content type="html"><![CDATA[<p>角色扮演的体验是否舒适主要受角色卡、大模型和生成时间三个因素的影响。</p><p>优秀的角色卡往往附带大量的设定,这会极大的拖慢第一次生成的时间,并且随着对话的进行,上下文长度很容易超过kv_cache的上限,这些很破坏沉浸式的体验。</p><p>此外,大模型在进行角色扮演时,除了进行必要的对话生成外,还需要生成旁白增加想象空间。</p><p>对博主这些相比填空更喜欢选项的玩家,给出提问建议也是非常必要的:在建议的基础上修改比自己从零写一个情景更简单,同时也完整保留了控制剧情走向的权力。</p><p>以上这些都让本就稀缺的kv_cache更加雪上加霜。</p><p>万幸,StreamingLLM 发现了kv_cache具有良好的平移性,而 llama.cpp 也提供了对kv_cache进行底层操作的api:可以指定范围的 kv_cache_seq_rm 和 kv_cache_seq_shift。基于这两个api,我们将实现对kv_cache的 token 级微操,榨干kv_cache的全部价值。</p><p>博主实践表明,在充分利用kv_cache的基础上,哪怕是 huggingface space 免费的2vCPU容器也可以游玩角色扮演,而笔记本端6G显存的1660Ti可以做到畅玩角色扮演。</p><h2 id="体验-DEMO">体验 DEMO</h2><ul><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9zcGFjZXMvTGltb3VyL2xsYW1hLXB5dGhvbi1zdHJlYW1pbmdsbG0=" rel="noopener external nofollow noreferrer">Limour/llama-python-streamingllm</a></li><li>同一时间仅支持一个人用,用之前点 Reset 按钮恢复初始的 kv_cache</li><li>按 Submit 没反应,说明有人在用,等一段时间后再 Reset</li><li>最好是 Duplicate 后,设为私密来使用</li></ul><h2 id="代码仓库">代码仓库</h2><ul><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvbGxhbWEtcHl0aG9uLXN0cmVhbWluZ2xsbQ==" rel="noopener external nofollow noreferrer">llama-python-streamingllm</a></li><li><a href="/-ji-lu--an-zhuang-conda-bing-geng-huan-qing-hua-yuan">安装conda</a></li><li><a href="/Use-Tunnel-to-speed-up-the-connection-of-VPS">学术上网</a>(管理员权限)</li><li>使用前需要修改 <code>rp_config.json</code> 里的模型路径和参数,指定为你已经下载了的<code>GGUF</code>格式模型的路径</li><li>推荐 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9UaGVCbG9rZS9DYXVzYWxMTS03Qi1HR1VGL2Jsb2IvbWFpbi9jYXVzYWxsbV83Yi5RNV9LX00uZ2d1Zg==" rel="noopener external nofollow noreferrer">causallm_7b.Q5_K_M.gguf</a></li><li>或者自己用 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9kYXRhc2V0cy9MaW1vdXIvYi1jb3JwdXM=" rel="noopener external nofollow noreferrer">Galgame</a> 解包的对话数据集微调一个合适的模型。</li></ul><h3 id="二选一:GPU版本的环境">二选一:GPU版本的环境</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs powershell">conda create <span class="hljs-literal">-n</span> llamaCpp libcublas cuda<span class="hljs-literal">-toolkit</span> git <span class="hljs-literal">-c</span> nvidia <span class="hljs-literal">-c</span> conda<span class="hljs-literal">-forge</span><br>conda activate llamaCpp<br>conda install python=<span class="hljs-number">3.10</span> gradio <span class="hljs-literal">-c</span> conda<span class="hljs-literal">-forge</span><br><span class="hljs-comment"># 然后去 release 下载相应的包 https://github.com/Limour-dev/llama-cpp-python-cuBLAS-wheels/releases</span><br>pip install <span class="hljs-literal">--force-reinstall</span> llama_cpp_python<span class="hljs-literal">-0</span>.<span class="hljs-number">2.39</span>+cu122<span class="hljs-literal">-cp310-cp310-win_amd64</span>.whl<br></code></pre></td></tr></table></figure><h3 id="二选一:CPU版本的环境">二选一:CPU版本的环境</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs powershell">conda create <span class="hljs-literal">-n</span> llamaCpp python=<span class="hljs-number">3.10</span> gradio git <span class="hljs-literal">-c</span> conda<span class="hljs-literal">-forge</span><br>conda activate llamaCpp<br>pip install llama<span class="hljs-literal">-cpp-python</span>==<span class="hljs-number">0.2</span>.<span class="hljs-number">39</span><br></code></pre></td></tr></table></figure><h3 id="下载并运行">下载并运行</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs powershell">conda activate llamaCpp<br>git clone <span class="hljs-literal">--depth</span>=<span class="hljs-number">1</span> https://github.com/Limour<span class="hljs-literal">-dev</span>/llama<span class="hljs-literal">-python-streamingllm</span>.git<br><span class="hljs-built_in">cd</span> llama<span class="hljs-literal">-python-streamingllm</span><br>mkdir cache<br>python .\gradio_streamingllm.py<br></code></pre></td></tr></table></figure><h2 id="核心内容">核心内容</h2><ul><li><code>Submit</code> 会将 msg 发送给模型,然后流式生成回答</li><li><code>Retry</code> 会重新生成最近一次的 msg 所对应的回答</li><li><code>旁白</code> 会流式生成一份旁白到 <code>VO</code> 框</li><li><code>建议</code> 会以 usr 的身份流式生成一份 msg 供修改</li><li>上面四个功能的基础就是下面的基于 StreamingLLM 原理的 venv 开头的函数</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">StreamingLLM</span>(<span class="hljs-title class_ inherited__">Llama</span>):<br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">kv_cache_seq_trim</span>(<span class="hljs-params">self</span>):<br> self._ctx.kv_cache_seq_rm(-<span class="hljs-number">1</span>, self.n_tokens, -<span class="hljs-number">1</span>)<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">kv_cache_seq_ltrim</span>(<span class="hljs-params">self, n_keep, n_discard=<span class="hljs-number">256</span>, n_past=-<span class="hljs-number">1</span></span>):<br> <span class="hljs-keyword">if</span> n_past &lt; <span class="hljs-number">0</span>:<br> n_past = self.n_tokens<br> self._ctx.kv_cache_seq_rm(-<span class="hljs-number">1</span>, n_keep, n_keep + n_discard)<br> self._ctx.kv_cache_seq_shift(<span class="hljs-number">0</span>, n_keep + n_discard, n_past, -n_discard)<br> self.input_ids[n_keep:n_past - n_discard] = self.input_ids[n_keep + n_discard:n_past]<br> self.n_tokens = n_past - n_discard<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">_venv_init</span>(<span class="hljs-params">self</span>):<br> self.venv = [<span class="hljs-number">0</span>]<br> self.venv_idx_map = []<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">venv_create</span>(<span class="hljs-params">self, name: <span class="hljs-built_in">str</span></span>):<br> self.venv.append(<span class="hljs-number">0</span>)<br> self.venv_idx_map.append(name)<br> <span class="hljs-keyword">return</span> name<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">venv_disband</span>(<span class="hljs-params">self, name_set</span>):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(self.venv) &lt;= <span class="hljs-number">1</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br> name_set = &#123;x <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> name_set <span class="hljs-keyword">if</span> x <span class="hljs-keyword">in</span> self.venv_idx_map&#125;<br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> name_set:<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br> <span class="hljs-keyword">while</span> self.venv_idx_map:<br> <span class="hljs-keyword">if</span> self.venv_idx_map[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> name_set:<br> self.venv_idx_map.pop(<span class="hljs-number">0</span>) <span class="hljs-comment"># 删除</span><br> tmp = self.venv.pop(<span class="hljs-number">1</span>) <span class="hljs-comment"># 对应的 venv 移入上一层</span><br> self.venv[<span class="hljs-number">0</span>] += tmp<br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">break</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span><br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">venv_revision</span>(<span class="hljs-params">self, name: <span class="hljs-built_in">str</span></span>):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(self.venv) &lt;= <span class="hljs-number">1</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br> <span class="hljs-keyword">if</span> name <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> self.venv_idx_map:<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br> _s = <span class="hljs-number">0</span><br> <span class="hljs-keyword">while</span> self.venv_idx_map:<br> <span class="hljs-keyword">if</span> self.venv_idx_map[-<span class="hljs-number">1</span>] == name:<br> <span class="hljs-keyword">break</span><br> self.venv_idx_map.pop() <span class="hljs-comment"># 删除</span><br> _s += self.venv.pop()<br> <span class="hljs-keyword">if</span> _s:<br> self.n_tokens -= <span class="hljs-built_in">min</span>(_s, self.n_tokens)<br> self.kv_cache_seq_trim()<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span><br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">venv_remove</span>(<span class="hljs-params">self, name: <span class="hljs-built_in">str</span></span>):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(self.venv) &lt;= <span class="hljs-number">1</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br> <span class="hljs-keyword">if</span> name <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> self.venv_idx_map:<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br> venv_idx = self.venv_idx_map.index(name) + <span class="hljs-number">1</span><br> <span class="hljs-keyword">while</span> self.venv_idx_map:<br> self.venv_idx_map.pop(venv_idx - <span class="hljs-number">1</span>) <span class="hljs-comment"># 删除</span><br> <span class="hljs-keyword">if</span> venv_idx == <span class="hljs-built_in">len</span>(self.venv) - <span class="hljs-number">1</span>:<br> <span class="hljs-comment"># 最后一层</span><br> self.n_tokens -= <span class="hljs-built_in">min</span>(self.venv.pop(), self.n_tokens)<br> self.kv_cache_seq_trim()<br> <span class="hljs-keyword">break</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-comment"># 非最后一层</span><br> n_keep = self.n_tokens - <span class="hljs-built_in">sum</span>(self.venv[i] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(venv_idx, <span class="hljs-built_in">len</span>(self.venv)))<br> n_discard = self.venv.pop(venv_idx)<br> self.kv_cache_seq_ltrim(n_keep, n_discard)<br> <span class="hljs-keyword">try</span>:<br> venv_idx = self.venv_idx_map.index(name, venv_idx - <span class="hljs-number">1</span>) + <span class="hljs-number">1</span><br> <span class="hljs-keyword">except</span> ValueError: <span class="hljs-comment"># 没有了</span><br> <span class="hljs-keyword">break</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span><br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">eval_t</span>(<span class="hljs-params">self, tokens, n_keep=<span class="hljs-number">4</span>, n_discard=<span class="hljs-number">256</span>, im_start=<span class="hljs-literal">None</span></span>):<br> <span class="hljs-keyword">if</span> self._n_ctx &lt; self.n_tokens + <span class="hljs-built_in">len</span>(tokens):<br> tmp_n_discard = <span class="hljs-built_in">max</span>(n_discard, self.n_tokens + <span class="hljs-built_in">len</span>(tokens) - self._n_ctx)<br> self.kv_cache_seq_ltrim(n_keep, tmp_n_discard)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, <span class="hljs-built_in">len</span>(tokens), self.n_batch):<br> <span class="hljs-keyword">pass</span><br> self.n_tokens += n_tokens<br> self.venv[-<span class="hljs-number">1</span>] += n_tokens<br></code></pre></td></tr></table></figure>]]></content>
  157. <summary type="html">&lt;p&gt;角色扮演的体验是否舒适主要受角色卡、大模型和生成时间三个因素的影响。&lt;/p&gt;
  158. &lt;p&gt;优秀的角色卡往往附带大量的设定,这会极大的拖慢第一次生成的时间,并且随着对话的进行,上下文长度很容易超过kv_cache的上限,这些很破坏沉浸式的体验。&lt;/p&gt;
  159. &lt;p&gt;此外,大模型在进行角色</summary>
  160. <category term="探索" scheme="https://hexo.limour.top/tags/%E6%8E%A2%E7%B4%A2/"/>
  161. <category term="llama" scheme="https://hexo.limour.top/tags/llama/"/>
  162. </entry>
  163. <entry>
  164. <title>【探索】将BlueLM-7B-Chat转换为标准的GGUF模型</title>
  165. <link href="https://hexo.limour.top/Convert-BlueLM-7B-Chat-to-the-standard-GGUF-model"/>
  166. <id>https://hexo.limour.top/Convert-BlueLM-7B-Chat-to-the-standard-GGUF-model</id>
  167. <published>2024-02-03T22:38:07.000Z</published>
  168. <updated>2024-03-19T08:07:10.321Z</updated>
  169. <content type="html"><![CDATA[<h2 id="准备模型">准备模型</h2><ul><li><a href="/Running-Qwen-on-the-Win10-platform-with-6GB-of-video-memory">运行环境</a></li></ul><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs powershell"><span class="hljs-comment"># conda create -n llamaConvert python=3.10 git -c conda-forge</span><br><span class="hljs-comment"># conda activate llamaConvert</span><br><span class="hljs-comment"># cd D:\llama</span><br><span class="hljs-comment"># git clone --depth=1 https://github.com/ggerganov/llama.cpp.git</span><br><span class="hljs-comment"># cd llama.cpp</span><br><span class="hljs-comment"># python -m pip install -r requirements.txt</span><br><span class="hljs-comment"># pip install tiktoken</span><br><span class="hljs-variable">$env:HF_ENDPOINT</span>=<span class="hljs-string">&quot;https://hf-mirror.com&quot;</span>; python <span class="hljs-literal">-c</span> <span class="hljs-string">&quot;from huggingface_hub import snapshot_download; snapshot_download(repo_id=&#x27;vivo-ai/BlueLM-7B-Chat-32K&#x27;, local_dir=r&#x27;D:\models\BlueLM-7B&#x27;)&quot;</span><br><span class="hljs-comment"># 还是用 vivo-ai/BlueLM-7B-Chat 吧, 32k的 ntkmixed 长度外推方案不知道怎么改</span><br></code></pre></td></tr></table></figure><ul><li>初始的模型结构</li></ul><figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs txt">BlueLMForCausalLM(<br> (model): BlueLMModel(<br> (embed_tokens): Embedding(100096, 4096, padding_idx=3)<br> (embed_layer_norm): LayerNorm((4096,), eps=1e-06, elementwise_affine=True)<br> (layers): ModuleList(<br> (0-31): 32 x BlueLMDecoderLayer(<br> (self_attn): BlueLMAttention(<br> (q_proj): Linear(in_features=4096, out_features=4096, bias=False)<br> (k_proj): Linear(in_features=4096, out_features=4096, bias=False)<br> (v_proj): Linear(in_features=4096, out_features=4096, bias=False)<br> (o_proj): Linear(in_features=4096, out_features=4096, bias=False)<br> (rotary_emb): BlueLMRotaryEmbedding()<br> )<br> (mlp): BlueLMMLP(<br> (gate_proj): Linear(in_features=4096, out_features=11008, bias=False)<br> (down_proj): Linear(in_features=11008, out_features=4096, bias=False)<br> (up_proj): Linear(in_features=4096, out_features=11008, bias=False)<br> (act_fn): SiLU()<br> (dropout): Dropout(p=0, inplace=False)<br> )<br> (input_layernorm): BlueLMRMSNorm()<br> (post_attention_layernorm): BlueLMRMSNorm()<br> )<br> )<br> (norm): BlueLMRMSNorm()<br> )<br> (lm_head): Linear(in_features=4096, out_features=100096, bias=False)<br>)<br></code></pre></td></tr></table></figure><h2 id="归一化-embed">归一化 embed</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModelForCausalLM<br><span class="hljs-keyword">import</span> torch<br><br><span class="hljs-comment"># 提前将 modeling_bluelm.py 中用到 flash_attn 的部分改成 None,反正不真运行,只需要模型结构</span><br>tmp = AutoModelForCausalLM.from_pretrained(<span class="hljs-string">r&#x27;D:\models\BlueLM-7B&#x27;</span>,<br> torch_dtype=torch.bfloat16,<br> trust_remote_code=<span class="hljs-literal">True</span>)<br><br>test_i = torch.arange(<span class="hljs-number">0</span>, <span class="hljs-number">10</span>, dtype=torch.long)<br><br>embedding = tmp.model.embed_tokens<br>layer_norm = tmp.model.embed_layer_norm<br><br>test_o_o = embedding(test_i)<br>test_o_o = layer_norm(test_o_o)<br><br><span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> embedding.parameters():<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(param.shape) &gt; <span class="hljs-number">1</span>:<br> param.data = layer_norm(param.data)<br><br>test_o_c = embedding(test_i)<br><br><span class="hljs-built_in">print</span>(torch.allclose(test_o_o, test_o_c, atol=<span class="hljs-number">1e-4</span>))<br><br><span class="hljs-keyword">del</span> tmp.model.embed_layer_norm<br>tmp.save_pretrained(<span class="hljs-string">r&#x27;D:\models\BlueLM&#x27;</span>)<br><span class="hljs-comment"># 记得将缺失的一些文件手动复制一下</span><br><span class="hljs-comment"># 顺便删掉config.json里的rope scaling type</span><br></code></pre></td></tr></table></figure><ul><li>删除 embed_layer_norm 后的结构</li></ul><figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs txt">BlueLMForCausalLM(<br> (model): BlueLMModel(<br> (embed_tokens): Embedding(100096, 4096, padding_idx=3)<br> (layers): ModuleList(<br> (0-31): 32 x BlueLMDecoderLayer(<br> (self_attn): BlueLMAttention(<br> (q_proj): Linear(in_features=4096, out_features=4096, bias=False)<br> (k_proj): Linear(in_features=4096, out_features=4096, bias=False)<br> (v_proj): Linear(in_features=4096, out_features=4096, bias=False)<br> (o_proj): Linear(in_features=4096, out_features=4096, bias=False)<br> (rotary_emb): BlueLMRotaryEmbedding()<br> )<br> (mlp): BlueLMMLP(<br> (gate_proj): Linear(in_features=4096, out_features=11008, bias=False)<br> (down_proj): Linear(in_features=11008, out_features=4096, bias=False)<br> (up_proj): Linear(in_features=4096, out_features=11008, bias=False)<br> (act_fn): SiLU()<br> (dropout): Dropout(p=0, inplace=False)<br> )<br> (input_layernorm): BlueLMRMSNorm()<br> (post_attention_layernorm): BlueLMRMSNorm()<br> )<br> )<br> (norm): BlueLMRMSNorm()<br> )<br> (lm_head): Linear(in_features=4096, out_features=100096, bias=False)<br>)<br></code></pre></td></tr></table></figure><h2 id="测试运行">测试运行</h2><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs powershell">conda activate llamaConvert<br><span class="hljs-built_in">cd</span> D:\llama\llama.cpp<br>python convert.py D:\models\BlueLM <span class="hljs-literal">--padvocab</span><br>Wrote D:\models\BlueLM\ggml<span class="hljs-literal">-model-f16</span>.gguf<br>conda activate llamaCpp<br><span class="hljs-built_in">cd</span> D:\llama<span class="hljs-literal">-cublas</span><br>.\quantize.exe D:\models\BlueLM\ggml<span class="hljs-literal">-model-f16</span>.gguf D:\models\BlueLM\ggml<span class="hljs-literal">-model-Q5_K_M</span>.gguf Q5_K_M<br>.\main.exe <span class="hljs-literal">-m</span> D:\models\BlueLM\ggml<span class="hljs-literal">-model-Q5_K_M</span>.gguf <span class="hljs-literal">-ngl</span> <span class="hljs-number">25</span> <span class="hljs-literal">-c</span> <span class="hljs-number">1024</span> <span class="hljs-literal">--interactive-first</span><br></code></pre></td></tr></table></figure>]]></content>
  170. <summary type="html">&lt;h2 id=&quot;准备模型&quot;&gt;准备模型&lt;/h2&gt;
  171. &lt;ul&gt;
  172. &lt;li&gt;&lt;a href=&quot;/Running-Qwen-on-the-Win10-platform-with-6GB-of-video-memory&quot;&gt;运行环境&lt;/a&gt;&lt;/li&gt;
  173. &lt;/ul&gt;
  174. &lt;figure class=&quot;h</summary>
  175. <category term="探索" scheme="https://hexo.limour.top/tags/%E6%8E%A2%E7%B4%A2/"/>
  176. <category term="llama" scheme="https://hexo.limour.top/tags/llama/"/>
  177. </entry>
  178. <entry>
  179. <title>【探索】从零开始训练 GPT</title>
  180. <link href="https://hexo.limour.top/training-gpt-from-scratch"/>
  181. <id>https://hexo.limour.top/training-gpt-from-scratch</id>
  182. <published>2024-01-18T14:19:11.000Z</published>
  183. <updated>2024-03-19T08:07:10.320Z</updated>
  184. <content type="html"><![CDATA[<p><img src="https://img.limour.top/2024/01/18/65a93c6a8065a.webp" alt="训练中..."></p><h2 id="预期结构">预期结构</h2><ul><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvSGVsbG9HUFQ=" rel="noopener external nofollow noreferrer">相关代码已经放到 Github</a></li></ul><figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs txt">HelloGPT(<br> (tok_embeddings): Embedding(32765, 768)<br> (rotary_emb): RotaryEmbedding(head_dim=64, max_seq_len=1024)<br> (layers): ModuleList(<br> (0-11): 12 x Decoder(<br> (ln1): RMSNorm(hidden_size=768, eps=1e-06)<br> (attn): Attention(<br> (q_proj): Linear(in_features=768, out_features=768, bias=False)<br> (k_proj): Linear(in_features=768, out_features=768, bias=False)<br> (v_proj): Linear(in_features=768, out_features=768, bias=False)<br> (o_proj): Linear(in_features=768, out_features=768, bias=False)<br> )<br> (ln2): RMSNorm(hidden_size=768, eps=1e-06)<br> (mlp): MLP(<br> (gate_proj): Linear(in_features=768, out_features=1536, bias=False)<br> (up_proj): Linear(in_features=768, out_features=1536, bias=False)<br> (down_proj): Linear(in_features=1536, out_features=768, bias=False)<br> )<br> )<br> )<br> (norm): RMSNorm(hidden_size=768, eps=1e-06)<br> (ln2): Linear(in_features=768, out_features=32765, bias=False)<br>)<br></code></pre></td></tr></table></figure><h2 id="配置环境">配置环境</h2><ul><li><a href="/-ji-lu--an-zhuang-conda-bing-geng-huan-qing-hua-yuan">安装conda</a></li></ul><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs powershell"><span class="hljs-built_in">cd</span> E:\GPT<br>conda install mamba <span class="hljs-literal">-c</span> conda<span class="hljs-literal">-forge</span><br>mamba create <span class="hljs-literal">-n</span> HelloGPT pytorch pytorch<span class="hljs-literal">-cuda</span>=<span class="hljs-number">12.1</span> <span class="hljs-literal">-c</span> pytorch <span class="hljs-literal">-c</span> nvidia <span class="hljs-literal">-c</span> conda<span class="hljs-literal">-forge</span><br>conda activate HelloGPT<br>conda install numpy transformers tiktoken tensorboard sentencepiece<span class="hljs-literal">-python</span> jieba emoji <span class="hljs-literal">-c</span> conda<span class="hljs-literal">-forge</span><br>pip install opencc<span class="hljs-literal">-python-reimplemented</span> <span class="hljs-literal">-i</span> https://pypi.tuna.tsinghua.edu.cn/simple<br>python test_cuda.py<br>python test_SPDA.py<br>D:\vscode\Code.exe<br></code></pre></td></tr></table></figure><h2 id="准备数据">准备数据</h2><ul><li>下载 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9jb2xsZWN0aW9ucy9MaW1vdXIvcjE4LW5vdmVscy1nYWxnYW1lLTY1OThmMTY4OTRjYWRjOWNkY2IzZjNhYg==" rel="noopener external nofollow noreferrer">h-corpus-2023</a></li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> os<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Fileset</span>(<span class="hljs-title class_ inherited__">list</span>):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, path, ext=<span class="hljs-string">&#x27;&#x27;</span>, _read=<span class="hljs-literal">None</span></span>):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">isinstance</span>(path, <span class="hljs-built_in">str</span>):<br> self.root = path<br> self.extend(f <span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> os.listdir(self.root) <span class="hljs-keyword">if</span> f.endswith(ext))<br> self._read = _read<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__getitem__</span>(<span class="hljs-params">self, index</span>):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">isinstance</span>(index, <span class="hljs-built_in">int</span>): <span class="hljs-comment"># index是索引</span><br> <span class="hljs-keyword">if</span> self._read:<br> <span class="hljs-keyword">return</span> self._read(os.path.join(self.root, <span class="hljs-built_in">super</span>().__getitem__(index)))<br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> os.path.join(self.root, <span class="hljs-built_in">super</span>().__getitem__(index))<br> <span class="hljs-keyword">else</span>: <span class="hljs-comment"># index是切片</span><br> fileset = Fileset(<span class="hljs-literal">None</span>)<br> fileset.root = self.root<br> fileset._read = self._read<br> fileset.extend(<span class="hljs-built_in">super</span>().__getitem__(index))<br> <span class="hljs-keyword">return</span> fileset<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">getFileName</span>(<span class="hljs-params">self, index</span>):<br> fname, ext = os.path.splitext(<span class="hljs-built_in">super</span>().__getitem__(index))<br> <span class="hljs-keyword">return</span> fname<br><br><br><span class="hljs-keyword">from</span> tokenizer <span class="hljs-keyword">import</span> tokenizer<br>token_eos = <span class="hljs-number">2</span><br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">readOne</span>(<span class="hljs-params">filePath</span>):<br> retn = []<br> <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(file=filePath, encoding=<span class="hljs-string">&#x27;utf-8&#x27;</span>) <span class="hljs-keyword">as</span> f:<br> <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> f:<br> retn += tokenizer.encode(line).ids<br> retn.append(token_eos)<br> <span class="hljs-keyword">return</span> retn<br><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Hcorpus</span>():<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, path, ext=<span class="hljs-string">&#x27;txt&#x27;</span>, fileset_idx=<span class="hljs-number">0</span>, fileset_sub_idx=<span class="hljs-number">0</span></span>):<br> self.fileset = Fileset(path, ext, readOne)<br> self.fileset_idx = fileset_idx<br> self.fileset_sub_idx = fileset_sub_idx<br> <span class="hljs-keyword">if</span> self.fileset_sub_idx &lt; <span class="hljs-number">0</span>: <span class="hljs-comment"># 再读上一个太复杂了,直接放弃</span><br> self.fileset_sub_idx = <span class="hljs-number">0</span><br> <span class="hljs-keyword">if</span> self.fileset_idx &gt;= <span class="hljs-built_in">len</span>(self.fileset):<br> self.fileset_idx = <span class="hljs-number">0</span><br> self.cache = self.fileset[self.fileset_idx]<br> self.fileset_idx += <span class="hljs-number">1</span><br> self.cache_idx = self.fileset_sub_idx<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__call__</span>(<span class="hljs-params">self, size=<span class="hljs-number">512</span></span>):<br> <span class="hljs-keyword">while</span> <span class="hljs-built_in">len</span>(self.cache) &lt; self.cache_idx + size:<br> <span class="hljs-keyword">if</span> self.fileset_idx &gt;= <span class="hljs-built_in">len</span>(self.fileset):<br> self.fileset_idx = <span class="hljs-number">0</span><br> self.fileset_sub_idx = self.cache_idx - <span class="hljs-built_in">len</span>(self.cache)<br> self.cache = self.cache[self.cache_idx:] + self.fileset[self.fileset_idx]<br> self.cache_idx = <span class="hljs-number">0</span><br> self.fileset_idx += <span class="hljs-number">1</span><br> retn = self.cache[self.cache_idx:self.cache_idx + size]<br> self.cache_idx += size<br> self.fileset_sub_idx += size<br> <span class="hljs-keyword">return</span> retn<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__repr__</span>(<span class="hljs-params">self</span>):<br> <span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;Hcorpus(r&#x27;<span class="hljs-subst">&#123;self.fileset.root&#125;</span>&#x27;, fileset_idx=<span class="hljs-subst">&#123;self.fileset_idx-<span class="hljs-number">1</span>&#125;</span>, fileset_sub_idx=<span class="hljs-subst">&#123;self.fileset_sub_idx&#125;</span>)&quot;</span><br></code></pre></td></tr></table></figure><h2 id="训练Tokenizer">训练Tokenizer</h2><ul><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9kb2NzL3Rva2VuaXplcnMvcXVpY2t0b3Vy" rel="noopener external nofollow noreferrer">tokenizer 包的文档</a></li><li>繁体转换成简体:<a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvSGVsbG9HUFQvYmxvYi9tYWluL3RyYWluX3Rva2VuaXplcl9wcmUucHk=" rel="noopener external nofollow noreferrer">train_tokenizer_pre.py</a></li><li>获取常用 emoji:<a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvSGVsbG9HUFQvYmxvYi9tYWluL3RtcF9lbW9qaS5weQ==" rel="noopener external nofollow noreferrer">tmp_emoji.py</a></li><li>分词统计词频:<a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvSGVsbG9HUFQvYmxvYi9tYWluL3RyYWluX3Rva2VuaXplcl9qaWViYS5weQ==" rel="noopener external nofollow noreferrer">tokenizer_jieba.py</a></li><li>区分词性并构造 BPE 语料:<a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvSGVsbG9HUFQvYmxvYi9tYWluL3RyYWluX3Rva2VuaXplcl9qaWViYV9zdGF0aXN0aWNzLnB5" rel="noopener external nofollow noreferrer">train_tokenizer_jieba_statistics.py</a></li><li>训练 BPE 模型:<a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvSGVsbG9HUFQvYmxvYi9tYWluL3RyYWluX3Rva2VuaXplci5weQ==" rel="noopener external nofollow noreferrer">train_tokenizer.py</a></li><li>最终训练好的 BPE 模型:<a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL0xpbW91ci1kZXYvSGVsbG9HUFQvYmxvYi9tYWluL0hlbGxvQlBFLnRva2VuaXplci5qc29u" rel="noopener external nofollow noreferrer">HelloBPE.tokenizer.json</a></li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> tokenizers <span class="hljs-keyword">import</span> Tokenizer<br>tokenizer = Tokenizer.from_file(<span class="hljs-string">&quot;HelloBPE.tokenizer.json&quot;</span>)<br></code></pre></td></tr></table></figure><h2 id="定义模型">定义模型</h2><h3 id="定义-Decoder">定义 Decoder</h3><h4 id="定义-RMSnorm">定义 RMSnorm</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">RMSNorm</span>(nn.Module):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, dim: <span class="hljs-built_in">int</span>, eps: <span class="hljs-built_in">float</span> = <span class="hljs-number">1e-6</span></span>):<br> <span class="hljs-built_in">super</span>().__init__()<br> self.eps = eps<br> self.weight = nn.Parameter(torch.ones(dim))<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">forward</span>(<span class="hljs-params">self, x</span>):<br> x = x * torch.rsqrt(x.<span class="hljs-built_in">pow</span>(<span class="hljs-number">2</span>).mean(-<span class="hljs-number">1</span>, keepdim=<span class="hljs-literal">True</span>) + self.eps)<br> <span class="hljs-keyword">return</span> x * self.weight<br></code></pre></td></tr></table></figure><h4 id="定义-RoPE">定义 RoPE</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">RotaryEmbedding</span>(nn.Module):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, head_dim: <span class="hljs-built_in">int</span>, max_seq_len: <span class="hljs-built_in">int</span>, device=device, theta: <span class="hljs-built_in">float</span> = <span class="hljs-number">10000.0</span></span>):<br> <span class="hljs-built_in">super</span>().__init__()<br> self.head_dim = head_dim<br> self.set_max_seq_len(max_seq_len, device, theta)<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">set_max_seq_len</span>(<span class="hljs-params">self, max_seq_len: <span class="hljs-built_in">int</span>, device=device, theta: <span class="hljs-built_in">float</span> = <span class="hljs-number">10000.0</span></span>):<br> self.max_seq_len = max_seq_len<br> freqs = <span class="hljs-number">1.0</span> / (theta ** (torch.arange(<span class="hljs-number">0</span>, self.head_dim, <span class="hljs-number">2</span>).<span class="hljs-built_in">float</span>().to(device) / self.head_dim))<br> t = torch.arange(max_seq_len, device=device) <span class="hljs-comment"># type: ignore</span><br> freqs = torch.outer(t, freqs).<span class="hljs-built_in">float</span>() <span class="hljs-comment"># 外积</span><br> self.freqs_cis = torch.polar(torch.ones_like(freqs), freqs) <span class="hljs-comment"># 复数,模 1,角度 freqs</span><br> self.freqs_cis.requires_grad = <span class="hljs-literal">False</span> <span class="hljs-comment"># filter(lambda p : p.requires_grad, model.parameters())</span><br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">rotary_emb</span>(<span class="hljs-params">self, x</span>):<br> x_ = torch.view_as_complex(x.<span class="hljs-built_in">float</span>().reshape(*x.shape[:-<span class="hljs-number">1</span>], -<span class="hljs-number">1</span>, <span class="hljs-number">2</span>))<br> x_out = torch.view_as_real(x_ * self.local_freqs_cis).flatten(<span class="hljs-number">3</span>)<br> <span class="hljs-keyword">return</span> x_out.type_as(x)<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">forward</span>(<span class="hljs-params">self, start_pos: <span class="hljs-built_in">int</span>, seqlen: <span class="hljs-built_in">int</span></span>):<br> self.local_freqs_cis = self.freqs_cis[start_pos: start_pos + seqlen].view(<span class="hljs-number">1</span>, seqlen, <span class="hljs-number">1</span>, -<span class="hljs-number">1</span>) <span class="hljs-comment"># cacheKV 相关,可忽略</span><br> self.local_freqs_cis.requires_grad = <span class="hljs-literal">False</span><br> <span class="hljs-keyword">return</span> self.rotary_emb<br></code></pre></td></tr></table></figure><h4 id="定义-Attention">定义 Attention</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Attention</span>(nn.Module):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, hidden_size, n_heads, cacheKV, max_batch_size, max_seq_len, device=device</span>):<br> <span class="hljs-built_in">super</span>().__init__()<br> self.n_heads = n_heads<br> self.head_dim = hidden_size // n_heads<br> self.q_proj = nn.Linear(hidden_size, hidden_size, bias=<span class="hljs-literal">False</span>)<br> self.k_proj = nn.Linear(hidden_size, hidden_size, bias=<span class="hljs-literal">False</span>)<br> self.v_proj = nn.Linear(hidden_size, hidden_size, bias=<span class="hljs-literal">False</span>)<br> self.o_proj = nn.Linear(hidden_size, hidden_size, bias=<span class="hljs-literal">False</span>)<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">forward</span>(<span class="hljs-params">self, hidden_states, rotary_emb, start_pos=<span class="hljs-number">0</span>, mask=<span class="hljs-literal">None</span>, is_causal=<span class="hljs-literal">True</span></span>):<br> bsz, seqlen, hidden_size = hidden_states.shape<br><br> q = self.q_proj(hidden_states)<br> k = self.k_proj(hidden_states)<br> v = self.v_proj(hidden_states)<br><br> q = q.view(bsz, seqlen, self.n_heads, self.head_dim)<br> k = k.view(bsz, seqlen, self.n_heads, self.head_dim)<br> v = v.view(bsz, seqlen, self.n_heads, self.head_dim)<br><br> q = rotary_emb(q)<br> k = rotary_emb(k)<br><br> q = q.transpose(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>) <span class="hljs-comment"># (bs, n_heads, seqlen, head_dim)</span><br> k = k.transpose(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>) <span class="hljs-comment"># (bs, n_local_heads, cache_len + seqlen, head_dim)</span><br> v = v.transpose(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>) <span class="hljs-comment"># (bs, n_local_heads, cache_len + seqlen, head_dim)</span><br><br> output = F.scaled_dot_product_attention(q, k, v, attn_mask=mask, is_causal=is_causal)<br><br> output = output.transpose(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>).contiguous().view(bsz, seqlen, hidden_size)<br> <span class="hljs-keyword">return</span> self.o_proj(output)<br></code></pre></td></tr></table></figure><h4 id="定义-MLP">定义 MLP</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">MLP</span>(nn.Module):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, hidden_size</span>):<br> <span class="hljs-built_in">super</span>().__init__()<br> intermediate_size = <span class="hljs-built_in">int</span>(<span class="hljs-number">2</span> * hidden_size)<br> self.gate_proj = nn.Linear(hidden_size, intermediate_size, bias=<span class="hljs-literal">False</span>)<br> self.up_proj = nn.Linear(hidden_size, intermediate_size, bias=<span class="hljs-literal">False</span>)<br> self.down_proj = nn.Linear(intermediate_size, hidden_size, bias=<span class="hljs-literal">False</span>)<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">forward</span>(<span class="hljs-params">self, x</span>):<br> gate = F.silu(self.gate_proj(x))<br> intermediate_states = self.up_proj(x)<br> <span class="hljs-keyword">return</span> self.down_proj(gate * intermediate_states)<br></code></pre></td></tr></table></figure><h4 id="组装-Decoder">组装 Decoder</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Decoder</span>(nn.Module):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, hidden_size, n_heads, cacheKV, max_batch_size, max_seq_len</span>):<br> <span class="hljs-built_in">super</span>().__init__()<br> self.ln1 = RMSNorm(hidden_size)<br> self.attn = Attention(hidden_size, n_heads, cacheKV, max_batch_size, max_seq_len)<br> self.ln2 = RMSNorm(hidden_size)<br> self.mlp = MLP(hidden_size)<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">forward</span>(<span class="hljs-params">self, x, rotary_emb, start_pos, mask=<span class="hljs-literal">None</span>, is_causal=<span class="hljs-literal">True</span></span>):<br> x = x + self.attn(self.ln1(x), rotary_emb, start_pos, mask, is_causal)<br> <span class="hljs-keyword">return</span> x + self.mlp(self.ln2(x))<br></code></pre></td></tr></table></figure><h3 id="组装模型">组装模型</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">HelloGPT</span>(nn.Module):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, vocab_size=<span class="hljs-number">32765</span>, hidden_size=<span class="hljs-number">768</span>, n_heads=<span class="hljs-number">12</span>, max_seq_len=<span class="hljs-number">1024</span>, n_layers=<span class="hljs-number">12</span>, cacheKV=<span class="hljs-literal">False</span>, max_batch_size=<span class="hljs-number">1</span></span>):<br> <span class="hljs-built_in">super</span>().__init__()<br> <span class="hljs-comment"># hidden_size &gt; 8.33 * ln(vocab_size)</span><br> self.tok_embeddings = nn.Embedding(vocab_size, hidden_size)<br> self.rotary_emb = RotaryEmbedding(hidden_size // n_heads, max_seq_len * <span class="hljs-number">2</span>)<br> self.rotary_emb.requires_grad = <span class="hljs-literal">False</span><br> self.layers = nn.ModuleList()<br> <span class="hljs-keyword">for</span> layer_id <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n_layers):<br> self.layers.append(Decoder(hidden_size, n_heads, cacheKV, max_batch_size, max_seq_len))<br> self.norm = RMSNorm(hidden_size)<br> self.ln2 = nn.Linear(hidden_size, vocab_size, bias=<span class="hljs-literal">False</span>)<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">forward</span>(<span class="hljs-params">self, input_ids: torch.Tensor, start_pos=<span class="hljs-number">0</span>, no_mask=<span class="hljs-literal">True</span></span>):<br> _bsz, seqlen = input_ids.shape<br> h = self.tok_embeddings(input_ids)<br><br> <span class="hljs-comment"># 预计算,减少每一层的重复计算</span><br> rotary_emb = self.rotary_emb(start_pos, seqlen)<br> <span class="hljs-keyword">for</span> layer <span class="hljs-keyword">in</span> self.layers:<br> h = layer(h, rotary_emb, start_pos)<br><br> h = self.norm(h)<br> h = self.ln2(h)<br> <span class="hljs-keyword">return</span> h.<span class="hljs-built_in">float</span>()<br></code></pre></td></tr></table></figure><h2 id="训练模型">训练模型</h2><h3 id="数据载入">数据载入</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs python">data = Hcorpus(<span class="hljs-string">r&#x27;D:\datasets\h-corpus&#x27;</span>)<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">get_batch</span>(<span class="hljs-params">size=<span class="hljs-number">512</span>, bsz=<span class="hljs-number">8</span></span>):<br> x = []<br> y = []<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(bsz):<br> tmp = data(size+<span class="hljs-number">1</span>)<br> x.append(tmp[:size])<br> y.append(tmp[<span class="hljs-number">1</span>:])<br> <span class="hljs-keyword">return</span> torch.tensor(x).to(device), torch.tensor(y).to(device)<br></code></pre></td></tr></table></figure><h3 id="模型载入">模型载入</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">model = HelloGPT(n_layers=<span class="hljs-number">8</span>, max_seq_len=<span class="hljs-number">768</span>)<br>model.to(device)<br></code></pre></td></tr></table></figure><h3 id="训练模型-2">训练模型</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment">## 初始化训练器</span><br>criterion = nn.CrossEntropyLoss() <span class="hljs-comment"># 交叉熵损失函数</span><br>optimizer = torch.optim.Adam(train_parameters, lr=<span class="hljs-number">6e-4</span>) <span class="hljs-comment"># Adam 优化器</span><br>scheduler = CosineAnnealingWarmRestarts(optimizer, T_0=<span class="hljs-number">5</span>, T_mult=<span class="hljs-number">2</span>) <span class="hljs-comment"># 余弦退火学习率</span><br>torch.manual_seed(<span class="hljs-number">1337</span>) <span class="hljs-comment"># 魔术随机种子</span><br><br>total_loss = <span class="hljs-number">0</span><br>print_iter = <span class="hljs-number">20</span><br><span class="hljs-keyword">for</span> epoch <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, <span class="hljs-number">100001</span>):<br> optimizer.zero_grad(set_to_none=<span class="hljs-literal">True</span>) <span class="hljs-comment"># 清空梯度,节省显存</span><br> x, y = get_batch(size=<span class="hljs-number">384</span>, bsz=<span class="hljs-number">4</span>) <span class="hljs-comment"># x 是训练语料 y 是 x 移动了一位,当做预测目标</span><br> y_ = model(x) <span class="hljs-comment"># 通过 x 预测的 y</span><br> loss = criterion(y_.view(-<span class="hljs-number">1</span>, <span class="hljs-number">32765</span>), y.view(-<span class="hljs-number">1</span>)) <span class="hljs-comment"># 计算损失</span><br> loss.backward() <span class="hljs-comment"># 反向传播梯度</span><br> torch.nn.utils.clip_grad_norm_(train_parameters, <span class="hljs-number">0.5</span>) <span class="hljs-comment"># 梯度裁剪,减轻过拟合</span><br> optimizer.step() <span class="hljs-comment"># 通过梯度优化训练参数</span><br> scheduler.step() <span class="hljs-comment"># 计算下一步的学习率</span><br> total_loss += loss <span class="hljs-comment"># 累计损失</span><br><br> <span class="hljs-keyword">if</span> epoch % print_iter == <span class="hljs-number">0</span>:<br> <span class="hljs-built_in">print</span>(data)<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">f&#x27;epoch: <span class="hljs-subst">&#123;epoch&#125;</span> lr: <span class="hljs-subst">&#123;scheduler.get_last_lr()[<span class="hljs-number">0</span>]:<span class="hljs-number">.4</span>e&#125;</span> loss: <span class="hljs-subst">&#123;total_loss / print_iter:<span class="hljs-number">.4</span>e&#125;</span>&#x27;</span>)<br> total_loss = <span class="hljs-number">0</span><br></code></pre></td></tr></table></figure><h3 id="保存读取">保存读取</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;tmp_training.pkl&#x27;</span>, <span class="hljs-string">&#x27;rb&#x27;</span>) <span class="hljs-keyword">as</span> file:<br> epoch = pickle.load(file) <span class="hljs-comment"># 读取 epoch 位置</span><br> tmp_fileset_idx = pickle.load(file) <span class="hljs-comment"># 读取 data 位置</span><br> tmp_fileset_sub_idx = pickle.load(file)<br><span class="hljs-comment"># 恢复数据位置</span><br>data = Hcorpus(<span class="hljs-string">r&#x27;D:\datasets\h-corpus&#x27;</span>, fileset_idx=tmp_fileset_idx-<span class="hljs-number">1</span>, fileset_sub_idx=tmp_fileset_sub_idx)<br>model = torch.load(<span class="hljs-string">f&#x27;tmp_model_<span class="hljs-subst">&#123;epoch&#125;</span>.pth&#x27;</span>) <span class="hljs-comment"># 恢复模型</span><br><span class="hljs-built_in">print</span>(<span class="hljs-string">f&#x27;start from epoch: <span class="hljs-subst">&#123;epoch&#125;</span> data: <span class="hljs-subst">&#123;data&#125;</span>&#x27;</span>)<br><br>save_iter = <span class="hljs-number">5000</span><br><span class="hljs-keyword">for</span> epoch <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, <span class="hljs-number">100001</span>):<br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">if</span> epoch % save_iter == <span class="hljs-number">0</span>:<br> optimizer.zero_grad(set_to_none=<span class="hljs-literal">True</span>) <span class="hljs-comment"># 清空梯度,节省显存</span><br> <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;tmp_training.pkl&#x27;</span>, <span class="hljs-string">&#x27;wb&#x27;</span>) <span class="hljs-keyword">as</span> file:<br> pickle.dump(epoch, file) <span class="hljs-comment"># 保存 epoch 位置</span><br> pickle.dump(data.fileset_idx, file) <span class="hljs-comment"># 保存 data 位置</span><br> pickle.dump(data.fileset_sub_idx, file)<br> torch.save(model, <span class="hljs-string">f&#x27;tmp_model_<span class="hljs-subst">&#123;epoch&#125;</span>.pth&#x27;</span>) <span class="hljs-comment"># 保存模型</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">f&#x27;save to tmp_model_<span class="hljs-subst">&#123;epoch&#125;</span>.pth&#x27;</span>)<br></code></pre></td></tr></table></figure><h3 id="可视化">可视化</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs python">writer = SummaryWriter(<span class="hljs-string">&#x27;logs&#x27;</span>) <span class="hljs-comment"># tensorboard --logdir logs</span><br><span class="hljs-keyword">for</span> epoch <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, <span class="hljs-number">100001</span>):<br> <span class="hljs-keyword">pass</span><br> writer.add_scalar(<span class="hljs-string">&#x27;lr&#x27;</span>, scheduler.get_last_lr()[<span class="hljs-number">0</span>], epoch)<br> writer.add_scalar(<span class="hljs-string">&#x27;loss&#x27;</span>, loss, epoch)<br> <span class="hljs-keyword">if</span> epoch % print_iter == <span class="hljs-number">0</span>:<br> <span class="hljs-keyword">pass</span><br> writer.add_scalar(<span class="hljs-string">&#x27;total_loss&#x27;</span>, total_loss / print_iter, epoch)<br>writer.close()<br></code></pre></td></tr></table></figure><h2 id="附加-streaming-llm">附加 streaming_llm</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">RotaryEmbedding</span>(nn.Module):<br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">inverse_rotary_emb</span>(<span class="hljs-params">self, x</span>):<br> x_ = torch.view_as_complex(x.<span class="hljs-built_in">float</span>().reshape(*x.shape[:-<span class="hljs-number">1</span>], -<span class="hljs-number">1</span>, <span class="hljs-number">2</span>))<br> x_out = torch.view_as_real(x_ * self.local_freqs_cis_inverse).flatten(<span class="hljs-number">3</span>)<br> <span class="hljs-keyword">return</span> x_out.type_as(x)<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">inverse_forward</span>(<span class="hljs-params">self, start_pos: <span class="hljs-built_in">int</span>, seqlen: <span class="hljs-built_in">int</span></span>):<br> self.local_freqs_cis_inverse = self.freqs_cis[start_pos: start_pos + seqlen].view(<span class="hljs-number">1</span>, seqlen, <span class="hljs-number">1</span>, -<span class="hljs-number">1</span>) <span class="hljs-comment"># cacheKV 相关,可忽略</span><br> self.local_freqs_cis_inverse = self.local_freqs_cis_inverse.conj() <span class="hljs-comment"># 乘上共轭就旋转回去了</span><br> self.local_freqs_cis.requires_grad = <span class="hljs-literal">False</span><br> <span class="hljs-keyword">return</span> self.inverse_rotary_emb<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Attention</span>(nn.Module):<br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">forward</span>(<span class="hljs-params">self, hidden_states, rotary_emb, start_pos=<span class="hljs-number">0</span>, mask=<span class="hljs-literal">None</span>, is_causal=<span class="hljs-literal">True</span></span>):<br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">if</span> self.cacheKV: <span class="hljs-comment"># cacheKV 相关,可忽略</span><br> self.cache_k[:bsz, start_pos: start_pos + seqlen] = k<br> self.cache_v[:bsz, start_pos: start_pos + seqlen] = v<br> k = self.cache_k[:bsz, : start_pos + seqlen]<br> v = self.cache_v[:bsz, : start_pos + seqlen]<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">streaming_llm</span>(<span class="hljs-params">self, start_pos, seqlen, to_pos, inverse_rotary_emb, rotary_emb, bsz</span>):<br> k = self.cache_k[:bsz, start_pos: start_pos + seqlen]<br> v = self.cache_v[:bsz, start_pos: start_pos + seqlen]<br> k = inverse_rotary_emb(k)<br> k = rotary_emb(k)<br> self.cache_k[:bsz, to_pos: to_pos + seqlen] = k<br> self.cache_v[:bsz, to_pos: to_pos + seqlen] = v<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">HelloGPT</span>(nn.Module):<br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">streaming_llm</span>(<span class="hljs-params">self, start_pos, seqlen, to_pos, max_batch_size=<span class="hljs-number">1</span></span>):<br> rotary_emb = self.rotary_emb(to_pos, seqlen)<br> inverse_rotary_emb = self.rotary_emb.inverse_forward(start_pos, seqlen)<br> <span class="hljs-keyword">for</span> layer <span class="hljs-keyword">in</span> self.layers:<br> layer.attn.streaming_llm(start_pos, seqlen, to_pos, inverse_rotary_emb, rotary_emb, max_batch_size)<br></code></pre></td></tr></table></figure>]]></content>
  185. <summary type="html">探索整个过程,从在一台搭载1660Ti显卡的笔记本电脑上构建 Tokenizer,定义带有 RoPE 的 Transformer,一直到训练、保存模型和可视化训练过程。沉浸在从零开始训练 GPT 的旅程中,深入了解每一个步骤。跳入深度学习的世界,释放在你的便携1660Ti笔记本上的强大潜能。</summary>
  186. <category term="探索" scheme="https://hexo.limour.top/tags/%E6%8E%A2%E7%B4%A2/"/>
  187. <category term="llama" scheme="https://hexo.limour.top/tags/llama/"/>
  188. </entry>
  189. <entry>
  190. <title>【避坑】Azure AI 避免反向薅羊毛</title>
  191. <link href="https://hexo.limour.top/Azure-AI-prevents-reverse-wool-shearing"/>
  192. <id>https://hexo.limour.top/Azure-AI-prevents-reverse-wool-shearing</id>
  193. <published>2024-01-09T05:55:40.000Z</published>
  194. <updated>2024-03-19T08:07:10.320Z</updated>
  195. <content type="html"><![CDATA[<h2 id="起因">起因</h2><p>今天收到 Azure 的付费邮件,一看账单,好家伙,24.54$ ,比上个月暴涨 622%,给我 CPU 干烧了。</p><p>赶紧去成本分析里按资源分类看上个月的扣费详情,然后就看到两个 10.33$ 的 <code>Container Registry</code>,分别位于我在 <a href="https://hexo.limour.top/go/#aHR0cDovL2FpLmF6dXJlLmNvbS8=" rel="noopener external nofollow noreferrer">Azure AI Studio</a> 里的两个不同项目所在区域。</p><p>一顿折腾,发现这个 Container Registry,有一年的免费试用期,但是免费限额是 31/个/天,一个 15 天刚好是 10.33$ 。</p><p>这 Azure 不讲武德,这样免费,头半个月根本不知道这东西要收费,等月末美滋滋去付账单时钱都已经扣完了。。。</p><p>特别是,这东西似乎是 Azure AI Studio 自动开通的,我根本没有用到过它。心情更糟了。</p><p><img src="https://img.limour.top/2024/01/09/659ce07c76fd0.webp" alt=""></p><h2 id="解决方案">解决方案</h2><p>赶紧去资源组里找到这两个<code>容器注册表</code>,全给删了。删除后不会对 Azure AI 的使用产生影响。</p><p>然后是想办法提工单,看能不能把这钱退回来。</p><p><img src="https://img.limour.top/2024/01/09/659ce568e9756.webp" alt="最后保留的服务,不知道哪些还可以删"></p><h2 id="工单结果">工单结果</h2><blockquote><p>透过案件了解到Container Registry是您不清楚的情况下创建的,且您已经将此资源进行了删除。考虑到您是首次使用Azure产品较不熟悉,且已经将资源删除,经过竭力向主管团队申请,现为您申请了相关费用的减免,即:<br>12/1/2023-12/31/2023期间由Container Registry – Standard产生的费用20.66 USD已经申请退回至您的信用卡,依据银行流程,款项约需要7-21个工作日抵达您的账户,届时请您查看。<br>同时,我们也查看了您当前的计费周期(1/1/2024-1/31/2024)的使用量报表,Container Registry – Standard未产生费用,还请您放心。</p></blockquote>]]></content>
  196. <summary type="html">&lt;h2 id=&quot;起因&quot;&gt;起因&lt;/h2&gt;
  197. &lt;p&gt;今天收到 Azure 的付费邮件,一看账单,好家伙,24.54$ ,比上个月暴涨 622%,给我 CPU 干烧了。&lt;/p&gt;
  198. &lt;p&gt;赶紧去成本分析里按资源分类看上个月的扣费详情,然后就看到两个 10.33$ 的 &lt;code&gt;Contai</summary>
  199. <category term="openai" scheme="https://hexo.limour.top/tags/openai/"/>
  200. </entry>
  201. <entry>
  202. <title>【记录】win10平台6G显存运行Qwen-1.8B</title>
  203. <link href="https://hexo.limour.top/Running-Qwen-on-the-Win10-platform-with-6GB-of-video-memory"/>
  204. <id>https://hexo.limour.top/Running-Qwen-on-the-Win10-platform-with-6GB-of-video-memory</id>
  205. <published>2024-01-01T03:11:36.000Z</published>
  206. <updated>2024-03-29T02:44:08.689Z</updated>
  207. <content type="html"><![CDATA[<p><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL2dnZXJnYW5vdi9sbGFtYS5jcHA=" rel="noopener external nofollow noreferrer">Llama.cpp</a> 能 CPU &amp; GPU 环境混合推理,这里记录一下在 windows10 平台上运行 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9Rd2VuL1F3ZW4tMV84Qg==" rel="noopener external nofollow noreferrer">Qwen-1.8B</a> 的过程,显卡是 1660Ti 。</p><h2 id="准备模型">准备模型</h2><ul><li><a href="/-ji-lu--an-zhuang-conda-bing-geng-huan-qing-hua-yuan">安装conda</a></li><li><a href="/Use-Tunnel-to-speed-up-the-connection-of-VPS">Tun模式</a>(管理员权限)</li></ul><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs powershell">conda create <span class="hljs-literal">-n</span> llamaConvert python=<span class="hljs-number">3.10</span> git <span class="hljs-literal">-c</span> conda<span class="hljs-literal">-forge</span><br>conda activate llamaConvert<br><span class="hljs-built_in">cd</span> D:\llama<br>git clone <span class="hljs-literal">--depth</span>=<span class="hljs-number">1</span> https://github.com/ggerganov/llama.cpp.git<br><span class="hljs-built_in">cd</span> llama.cpp<br>python <span class="hljs-literal">-m</span> pip install <span class="hljs-literal">-r</span> requirements.txt<br>pip install tiktoken<br></code></pre></td></tr></table></figure><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs powershell">python <span class="hljs-literal">-c</span> <span class="hljs-string">&quot;from huggingface_hub import snapshot_download; snapshot_download(repo_id=&#x27;Qwen/Qwen-1_8B-Chat&#x27;, local_dir=r&#x27;D:\qwen&#x27;, ignore_patterns=[&#x27;*.h5&#x27;, &#x27;*.ot&#x27;, &#x27;*.msgpack&#x27;, &#x27;*.safetensors&#x27;])&quot;</span><br><span class="hljs-built_in">cd</span> D:\qwen<br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;model-00001-of-00002.safetensors&#x27;</span> <span class="hljs-string">&quot;https://huggingface.co/Qwen/Qwen-1_8B-Chat/resolve/main/model-00001-of-00002.safetensors?download=true&quot;</span><br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;model-00002-of-00002.safetensors&#x27;</span> <span class="hljs-string">&quot;https://huggingface.co/Qwen/Qwen-1_8B-Chat/resolve/main/model-00002-of-00002.safetensors?download=true&quot;</span><br></code></pre></td></tr></table></figure><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs powershell"><span class="hljs-built_in">cd</span> D:\llama\llama.cpp<br>python <span class="hljs-built_in">convert-hf</span><span class="hljs-literal">-to-gguf</span>.py D:\qwen<br><span class="hljs-comment"># Model successfully exported to &#x27;D:\qwen\ggml-model-f16.gguf&#x27;</span><br></code></pre></td></tr></table></figure><h2 id="运行模型">运行模型</h2><ul><li>下载 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL2dnZXJnYW5vdi9sbGFtYS5jcHAvcmVsZWFzZXM=" rel="noopener external nofollow noreferrer">llama-b1732-bin-win-cublas-cu12.2.0-x64.zip</a></li><li>提取文件到 <code>D:\llama</code></li></ul><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs powershell">conda create <span class="hljs-literal">-n</span> llamaCpp libcublas cuda<span class="hljs-literal">-toolkit</span> git <span class="hljs-literal">-c</span> nvidia <span class="hljs-literal">-c</span> conda<span class="hljs-literal">-forge</span><br>conda activate llamaCpp<br><span class="hljs-built_in">cd</span> D:\llama ; .\main.exe <span class="hljs-comment">## 检查能否正确运行</span><br><span class="hljs-built_in">cd</span> D:\llama ; .\quantize.exe <span class="hljs-literal">--help</span> <span class="hljs-comment">## 自己决定量化方式</span><br>.\quantize.exe D:\qwen\ggml<span class="hljs-literal">-model-f16</span>.gguf .\qwen<span class="hljs-literal">-1_8-f16</span>.gguf <span class="hljs-built_in">COPY</span><br>.\server.exe <span class="hljs-literal">-m</span> .\qwen<span class="hljs-literal">-1_8-f16</span>.gguf <span class="hljs-literal">-c</span> <span class="hljs-number">4096</span> <span class="hljs-literal">--n-gpu-layers</span> <span class="hljs-number">50</span> <span class="hljs-comment">## 调节 n-gpu-layers 平衡 CPU &amp; GPU</span><br></code></pre></td></tr></table></figure><ul><li>访问 <code>http://127.0.0.1:8080</code> 选择 <code>Completion</code> 进行测试</li></ul><h2 id="微调模型">微调模型</h2><ul><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9kYXRhc2V0cy9hNjg2ZDM4MC9oLWNvcnB1cy0yMDIz" rel="noopener external nofollow noreferrer">h-corpus数据集</a></li><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL1F3ZW5MTS9Rd2VuL2Jsb2IvbWFpbi9SRUFETUVfQ04ubWQjJUU1JUJFJUFFJUU4JUIwJTgz" rel="noopener external nofollow noreferrer">官方微调教程</a></li></ul><h2 id="附加-Yi-6B-Chat">附加 Yi-6B-Chat</h2><p><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby8wMS1haS9ZaS02Qi1DaGF0" rel="noopener external nofollow noreferrer">Yi-6B</a>是零一万物开源的双语语言模型,经过3T多语种语料库的训练,在语言理解、常识推理、阅读理解等方面有一定潜力。</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs powershell"><span class="hljs-built_in">cd</span> D:\models\<span class="hljs-number">01</span>yi<br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;model-00001-of-00003.safetensors&#x27;</span> <span class="hljs-string">&quot;https://huggingface.co/01-ai/Yi-6B-Chat/resolve/main/model-00001-of-00003.safetensors?download=true&quot;</span><br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;model-00002-of-00003.safetensors&#x27;</span> <span class="hljs-string">&quot;https://huggingface.co/01-ai/Yi-6B-Chat/resolve/main/model-00002-of-00003.safetensors?download=true&quot;</span><br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;model-00003-of-00003.safetensors&#x27;</span> https://huggingface.co/<span class="hljs-number">01</span><span class="hljs-literal">-ai</span>/Yi<span class="hljs-literal">-6B-Chat</span>/resolve/main/model<span class="hljs-literal">-00003-of-00003</span>.safetensors?download=true<br>conda activate llamaConvert<br>python <span class="hljs-literal">-c</span> <span class="hljs-string">&quot;from huggingface_hub import snapshot_download; snapshot_download(repo_id=&#x27;01-ai/Yi-6B-Chat&#x27;, local_dir=r&#x27;D:\models\01yi&#x27;, ignore_patterns=[&#x27;*.h5&#x27;, &#x27;*.ot&#x27;, &#x27;*.msgpack&#x27;, &#x27;*.safetensors&#x27;])&quot;</span><br></code></pre></td></tr></table></figure><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs powershell">conda activate llamaConvert<br><span class="hljs-built_in">cd</span> D:\llama\llama.cpp<br>python convert.py D:\models\<span class="hljs-number">01</span>yi<br><span class="hljs-comment"># Wrote D:\models\01yi\ggml-model-f16.gguf</span><br>conda activate llamaCpp<br><span class="hljs-built_in">cd</span> D:\llama ; .\quantize.exe <span class="hljs-literal">--help</span><br>.\quantize.exe D:\models\<span class="hljs-number">01</span>yi\ggml<span class="hljs-literal">-model-f16</span>.gguf .\<span class="hljs-number">01</span>yi<span class="hljs-literal">-6b-Q4_K_M</span>.gguf Q4_K_M<br>.\server.exe <span class="hljs-literal">-m</span> .\<span class="hljs-number">01</span>yi<span class="hljs-literal">-6b-Q4_K_M</span>.gguf <span class="hljs-literal">-c</span> <span class="hljs-number">4096</span> <span class="hljs-literal">--n-gpu-layers</span> <span class="hljs-number">50</span><br></code></pre></td></tr></table></figure><h2 id="附加-百川2">附加 百川2</h2><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs powershell"><span class="hljs-built_in">cd</span> D:\models\baichuan<br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;pytorch_model.bin&#x27;</span> <span class="hljs-string">&quot;https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/pytorch_model.bin?download=true&quot;</span><br>conda activate llamaConvert<br>python <span class="hljs-literal">-c</span> <span class="hljs-string">&quot;from huggingface_hub import snapshot_download; snapshot_download(repo_id=&#x27;baichuan-inc/Baichuan2-7B-Chat&#x27;, local_dir=r&#x27;D:\models\baichuan&#x27;, ignore_patterns=[&#x27;*.h5&#x27;, &#x27;*.bin&#x27;, &#x27;*.ot&#x27;, &#x27;*.msgpack&#x27;, &#x27;*.safetensors&#x27;])&quot;</span><br><span class="hljs-built_in">cd</span> D:\llama\llama.cpp<br>python convert.py D:\models\baichuan<br><span class="hljs-comment"># Wrote D:\models\baichuan\ggml-model-f16.gguf</span><br>conda activate llamaCpp<br><span class="hljs-built_in">cd</span> D:\llama ; .\quantize.exe <span class="hljs-literal">--help</span><br>.\quantize.exe D:\models\baichuan\ggml<span class="hljs-literal">-model-f16</span>.gguf .\baichuan<span class="hljs-literal">-7b-Q3_K_M</span>.gguf Q3_K_M<br>.\server.exe <span class="hljs-literal">-m</span> .\baichuan<span class="hljs-literal">-7b-Q3_K_M</span>.gguf <span class="hljs-literal">-c</span> <span class="hljs-number">2048</span> <span class="hljs-literal">--n-gpu-layers</span> <span class="hljs-number">30</span><br></code></pre></td></tr></table></figure><h2 id="附加-tigerbot-13b">附加 tigerbot-13b</h2><p><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9UaWdlclJlc2VhcmNoL3RpZ2VyYm90LTEzYi1jaGF0LXY1" rel="noopener external nofollow noreferrer">tigerbot-13b</a> 在 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL2plaW5sZWUxOTkxL2NoaW5lc2UtbGxtLWJlbmNobWFyaw==" rel="noopener external nofollow noreferrer">chinese-llm-benchmark</a> 上排名靠前。</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs powershell"><span class="hljs-built_in">cd</span> D:\models\tigerbot<br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;pytorch_model-00001-of-00003.bin&#x27;</span> <span class="hljs-literal">--max-download-limit</span>=<span class="hljs-number">6</span>M <span class="hljs-string">&quot;https://huggingface.co/TigerResearch/tigerbot-13b-chat-v5/resolve/main/pytorch_model-00001-of-00003.bin?download=true&quot;</span><br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;pytorch_model-00002-of-00003.bin&#x27;</span> <span class="hljs-literal">--max-download-limit</span>=<span class="hljs-number">6</span>M <span class="hljs-string">&quot;https://huggingface.co/TigerResearch/tigerbot-13b-chat-v5/resolve/main/pytorch_model-00002-of-00003.bin?download=true&quot;</span><br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;pytorch_model-00003-of-00003.bin&#x27;</span> <span class="hljs-literal">--max-download-limit</span>=<span class="hljs-number">6</span>M <span class="hljs-string">&quot;https://huggingface.co/TigerResearch/tigerbot-13b-chat-v5/resolve/main/pytorch_model-00003-of-00003.bin?download=true&quot;</span><br>conda activate llamaConvert<br>python <span class="hljs-literal">-c</span> <span class="hljs-string">&quot;from huggingface_hub import snapshot_download; snapshot_download(repo_id=&#x27;TigerResearch/tigerbot-13b-chat-v5&#x27;, local_dir=r&#x27;D:\models\tigerbot&#x27;, ignore_patterns=[&#x27;*.h5&#x27;, &#x27;*.bin&#x27;, &#x27;*.ot&#x27;, &#x27;*.msgpack&#x27;, &#x27;*.safetensors&#x27;])&quot;</span><br><span class="hljs-built_in">cd</span> D:\llama\llama.cpp<br>python convert.py D:\models\tigerbot <span class="hljs-literal">--padvocab</span><br><span class="hljs-built_in">cd</span> D:\llama ; .\quantize.exe <span class="hljs-literal">--help</span><br>.\quantize.exe D:\models\tigerbot\ggml<span class="hljs-literal">-model-f16</span>.gguf D:\models\tigerbot<span class="hljs-literal">-13B-Chat-Q4_K_M</span>.gguf Q4_K_M<br>.\server.exe <span class="hljs-literal">-m</span> D:\models\tigerbot<span class="hljs-literal">-13B-Chat-Q4_K_M</span>.gguf <span class="hljs-literal">-c</span> <span class="hljs-number">4096</span><br></code></pre></td></tr></table></figure><div class="note note-info"> <p>感觉 6G 显存下,比较好用的是 Yi-6B-Chat-Q4_K_M<br>tigerbot-13b 在 R5 5600H 上推理速度 4.6 tokens/s,CPU 使用率 60%,频率 3.5GHz,应该是内存带宽瓶颈</p> </div><h2 id="附加-在-Colab-上量化">附加 在 Colab 上量化</h2><ul><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9jb2xhYi5yZXNlYXJjaC5nb29nbGUuY29tL2RyaXZlLzFKVDNYRmpEN0NUUkI5N3B1M1FwZUd1eldBMXlZRUFNNz91c3A9c2hhcmluZw==" rel="noopener external nofollow noreferrer">llm2gguf.ipynb</a></li><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9MaW1vdXIvQ2F1c2FsTE0tMTRCLUdHVUY=" rel="noopener external nofollow noreferrer">量化后的结果</a></li></ul><h3 id="安装-llama-cpp">安装 llama.cpp</h3><figure class="highlight ipython"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs ipython">!git clone --depth=<span class="hljs-number">1</span> https://github.com/ggerganov/llama.cpp.git<br>%cd /content/llama.cpp<br>!LLAMA_CUDA=<span class="hljs-number">1</span> make -j<br></code></pre></td></tr></table></figure><h3 id="计算-imatrix">计算 imatrix</h3><figure class="highlight ipython"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs ipython">%cd /content<br>!wget -O transient.txt.gz https://huggingface.co/datasets/Limour/b-corpus/resolve/main/<span class="hljs-number">00</span>-preview/<span class="hljs-number">00</span>-transient.txt.gz?download=true<br>!gunzip transient.txt.gz<br>!mkdir -p /content/CausalLM-14B-GGUF<br>!wget -O /content/CausalLM-14B-GGUF/causallm_14b.Q8_0.gguf https://huggingface.co/TheBloke/CausalLM-14B-GGUF/resolve/main/causallm_14b.Q8_0.gguf?download=true<br>!/content/llama.cpp/imatrix -m /content/CausalLM-14B-GGUF/causallm_14b.Q8_0.gguf -f /content/transient.txt -ngl <span class="hljs-number">36</span><br></code></pre></td></tr></table></figure><h3 id="登录拥抱脸">登录拥抱脸</h3><figure class="highlight ipython"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs ipython"><span class="hljs-keyword">from</span> google.colab <span class="hljs-keyword">import</span> userdata<br><span class="hljs-keyword">from</span> huggingface_hub <span class="hljs-keyword">import</span> login<br><span class="hljs-comment"># login(token=os.environ.get(&quot;HF_TOKEN&quot;), write_permission=True)</span><br>login(token=userdata.get(<span class="hljs-string">&#x27;HF_TOKEN&#x27;</span>), write_permission=<span class="hljs-literal">True</span>)<br><span class="hljs-comment"># from huggingface_hub import notebook_login</span><br><span class="hljs-comment"># notebook_login()</span><br></code></pre></td></tr></table></figure><h3 id="跳过-转换模型">(跳过) 转换模型</h3><figure class="highlight ipython"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs ipython">%cd llama.cpp<br>!python -m pip install -r requirements.txt<br>!pip install tiktoken<br><span class="hljs-keyword">from</span> huggingface_hub <span class="hljs-keyword">import</span> snapshot_download<br>!mkdir -p ~/CausalLM<br>snapshot_download(repo_id=<span class="hljs-string">&#x27;CausalLM/7B&#x27;</span>, local_dir=<span class="hljs-string">r&#x27;/content/CausalLM&#x27;</span>, ignore_patterns=[<span class="hljs-string">&#x27;*.h5&#x27;</span>, <span class="hljs-string">&#x27;*.ot&#x27;</span>, <span class="hljs-string">&#x27;*.msgpack&#x27;</span>, <span class="hljs-string">&#x27;*.safetensors&#x27;</span>])<br>!python convert.py --vocab-<span class="hljs-built_in">type</span> bpe --pad-vocab --outtype f16 /content/CausalLM <br></code></pre></td></tr></table></figure><h3 id="量化模型">量化模型</h3><figure class="highlight ipython"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ipython">!/content/llama.cpp/quantize --allow-requantize --imatrix /content/imatrix.dat /content/CausalLM-14B-GGUF/causallm_14b.Q8_0.gguf /content/CausalLM-14B-GGUF/causallm_14b.IQ3_XS.gguf IQ3_XS<br></code></pre></td></tr></table></figure><h3 id="上传模型">上传模型</h3><figure class="highlight ipython"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs ipython"><span class="hljs-keyword">from</span> huggingface_hub <span class="hljs-keyword">import</span> HfApi<br>api = HfApi()<br>api.upload_file(<br> path_or_fileobj=<span class="hljs-string">&quot;/content/CausalLM-14B-GGUF/causallm_14b.IQ3_XS.gguf&quot;</span>,<br> path_in_repo=<span class="hljs-string">&quot;causallm_14b.IQ3_XS.gguf&quot;</span>,<br> repo_id=<span class="hljs-string">&quot;Limour/CausalLM-14B-GGUF&quot;</span><br>)<br></code></pre></td></tr></table></figure>]]></content>
  208. <summary type="html">&lt;p&gt;&lt;a href=&quot;https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL2dnZXJnYW5vdi9sbGFtYS5jcHA=&quot; rel=&quot;noopener external nofollow noreferrer&quot;&gt;Ll</summary>
  209. <category term="llama" scheme="https://hexo.limour.top/tags/llama/"/>
  210. </entry>
  211. <entry>
  212. <title>【记录】轻量个人导航页面 Flare</title>
  213. <link href="https://hexo.limour.top/Lightweight-personal-navigation-page-Flare"/>
  214. <id>https://hexo.limour.top/Lightweight-personal-navigation-page-Flare</id>
  215. <published>2023-12-31T17:18:28.000Z</published>
  216. <updated>2024-03-19T08:07:10.320Z</updated>
  217. <content type="html"><![CDATA[<p><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL3NvdWx0ZWFyeS9kb2NrZXItZmxhcmU=" rel="noopener external nofollow noreferrer">Flare</a> 是一款轻量、快速、美观的个人导航页面,适用于 HomeLab 或其他注重私密的场景。</p><ul><li><a href="/Docker-bu-shu-Nginx-Proxy-Manager">反向代理服务</a></li><li>访问 <code>https://flare.limour.top/editor</code> 进行书签编辑</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">mkdir</span> -p ~/app/flare &amp;&amp; <span class="hljs-built_in">cd</span> ~/app/flare &amp;&amp; nano docker-compose.yml<br>sudo docker-compose up -d <span class="hljs-comment"># flare:5005</span><br>sudo docker-compose logs <span class="hljs-comment"># 获取登录密码</span><br></code></pre></td></tr></table></figure><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs yml"><span class="hljs-attr">version:</span> <span class="hljs-string">&#x27;3.6&#x27;</span><br> <br><span class="hljs-attr">services:</span><br> <span class="hljs-attr">flare:</span><br> <span class="hljs-attr">image:</span> <span class="hljs-string">soulteary/flare</span><br> <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span><br> <span class="hljs-comment"># 默认无需添加任何参数,如有特殊需求</span><br> <span class="hljs-comment"># 可阅读文档 https://github.com/soulteary/docker-flare/blob/main/docs/advanced-startup.md</span><br> <span class="hljs-comment"># 启用账号登录模式</span><br> <span class="hljs-attr">command:</span> <span class="hljs-string">flare</span> <span class="hljs-string">--disable_login=0</span><br> <span class="hljs-attr">environment:</span><br> <span class="hljs-comment"># 如需开启用户登录模式,需要先设置 `nologin` 启动参数为 `0`</span><br> <span class="hljs-comment"># 如开启 `nologin`,未设置 FLARE_USER,则默认用户为 `flare`</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">FLARE_USER=LimourFlare</span><br> <span class="hljs-comment"># 指定你自己的账号密码,默认生成的密码强度堪忧</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">FLARE_PASS=your_password</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">FLARE_OFFLINE=1</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">FLARE_MINI_REQUEST=1</span><br> <span class="hljs-attr">volumes:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">./app:/app</span><br> <br><span class="hljs-attr">networks:</span><br> <span class="hljs-attr">default:</span><br> <span class="hljs-attr">external:</span> <span class="hljs-literal">true</span><br> <span class="hljs-attr">name:</span> <span class="hljs-string">ngpm</span><br></code></pre></td></tr></table></figure>]]></content>
  218. <summary type="html">&lt;p&gt;&lt;a href=&quot;https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL3NvdWx0ZWFyeS9kb2NrZXItZmxhcmU=&quot; rel=&quot;noopener external nofollow noreferrer</summary>
  219. <category term="docker" scheme="https://hexo.limour.top/tags/docker/"/>
  220. <category term="ngpm" scheme="https://hexo.limour.top/tags/ngpm/"/>
  221. <category term="homepage" scheme="https://hexo.limour.top/tags/homepage/"/>
  222. </entry>
  223. <entry>
  224. <title>【记录】Win10平台使用MLC-LLM编译Qwen-1.8B-Chat</title>
  225. <link href="https://hexo.limour.top/Compile-Qwen-1.8B-Chat-using-MLC-LLM-on-Win"/>
  226. <id>https://hexo.limour.top/Compile-Qwen-1.8B-Chat-using-MLC-LLM-on-Win</id>
  227. <published>2023-12-09T04:24:07.000Z</published>
  228. <updated>2024-03-19T08:07:10.319Z</updated>
  229. <content type="html"><![CDATA[<p><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL21sYy1haS9tbGMtbGxt" rel="noopener external nofollow noreferrer">MLC-LLM</a> 是一种大模型高性能通用部署解决方案,可以通过预编译加速使用本机API原生部署任何大型语言模型。该项目的使命是利用ML编译技术,使每个人都能在其设备上本地开发、优化和部署AI模型。<br><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9Rd2VuL1F3ZW4tMV84Qg==" rel="noopener external nofollow noreferrer">Qwen-1.8B</a> 是阿里云研发的通义千问大模型系列的18亿参数规模的模型。在Qwen-1.8B的基础上,使用对齐机制打造了基于大语言模型的AI助手 <a href="https://hexo.limour.top/go/#aHR0cHM6Ly9odWdnaW5nZmFjZS5jby9Rd2VuL1F3ZW4tMV84Qi1DaGF0" rel="noopener external nofollow noreferrer">Qwen-1.8B-Chat</a>。</p><h2 id="配置环境">配置环境</h2><ul><li><a href="/-ji-lu--an-zhuang-conda-bing-geng-huan-qing-hua-yuan">安装conda</a></li><li><a href="/Use-Tunnel-to-speed-up-the-connection-of-VPS">Tun模式</a>(管理员权限)</li><li><a href="https://hexo.limour.top/go/#aHR0cHM6Ly9sbG0ubWxjLmFpL2RvY3MvaW5zdGFsbC90dm0uaHRtbCNpbnN0YWxsLXR2bS11bml0eQ==" rel="noopener external nofollow noreferrer">详细流程</a></li></ul><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs powershell">conda create <span class="hljs-literal">-n</span> mlc_llm python numpy pytorch transformers scipy timm git <span class="hljs-literal">-c</span> pytorch <span class="hljs-literal">-c</span> conda<span class="hljs-literal">-forge</span><br>conda activate mlc_llm<br>python <span class="hljs-literal">-m</span> pip install <span class="hljs-literal">--pre</span> <span class="hljs-literal">-U</span> <span class="hljs-operator">-f</span> https://mlc.ai/wheels mlc<span class="hljs-literal">-ai-nightly</span><br>python <span class="hljs-literal">-c</span> <span class="hljs-string">&quot;import tvm; print(&#x27;\n&#x27;.join(f&#x27;&#123;k&#125;: &#123;v&#125;&#x27; for k, v in tvm.support.libinfo().items()))&quot;</span><br>python <span class="hljs-literal">-c</span> <span class="hljs-string">&quot;import tvm; print(tvm.vulkan().exist)&quot;</span><br><span class="hljs-built_in">cd</span> D:\mlc<span class="hljs-literal">-llm</span><br>git clone <span class="hljs-literal">--depth</span>=<span class="hljs-number">1</span> <span class="hljs-literal">-b</span> main <span class="hljs-literal">--single-branch</span> https://github.com/mlc<span class="hljs-literal">-ai</span>/mlc<span class="hljs-literal">-llm</span>.git<br><span class="hljs-built_in">cd</span> .\mlc<span class="hljs-literal">-llm</span>\<br>git submodule sync<br>git submodule update <span class="hljs-literal">--init</span> <span class="hljs-literal">--recursive</span> <span class="hljs-literal">--depth</span>=<span class="hljs-number">1</span><br>pip install .<br>python <span class="hljs-literal">-m</span> mlc_llm.build <span class="hljs-literal">--help</span><br></code></pre></td></tr></table></figure><h2 id="准备模型">准备模型</h2><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs powershell">python <span class="hljs-literal">-c</span> <span class="hljs-string">&quot;from huggingface_hub import snapshot_download; snapshot_download(repo_id=&#x27;Qwen/Qwen-1_8B-Chat&#x27;, local_dir=&#x27;D:\mlc-llm\qwen&#x27;, ignore_patterns=[&#x27;*.h5&#x27;, &#x27;*.ot&#x27;, &#x27;*.msgpack&#x27;, &#x27;*.safetensors&#x27;])&quot;</span><br><span class="hljs-built_in">cd</span> D:\mlc<span class="hljs-literal">-llm</span>\qwen<br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;model-00001-of-00002.safetensors&#x27;</span> <span class="hljs-string">&quot;https://huggingface.co/Qwen/Qwen-1_8B-Chat/resolve/main/model-00001-of-00002.safetensors?download=true&quot;</span><br>D:\aria2\aria2c.exe <span class="hljs-literal">--all-proxy</span>=<span class="hljs-string">&#x27;http://127.0.0.1:7890&#x27;</span> <span class="hljs-literal">-o</span> <span class="hljs-string">&#x27;model-00002-of-00002.safetensors&#x27;</span> <span class="hljs-string">&quot;https://huggingface.co/Qwen/Qwen-1_8B-Chat/resolve/main/model-00002-of-00002.safetensors?download=true&quot;</span><br></code></pre></td></tr></table></figure><h2 id="编译模型">编译模型</h2><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs powershell"><span class="hljs-built_in">cd</span> D:\mlc<span class="hljs-literal">-llm</span>\dist<br>python <span class="hljs-literal">-m</span> mlc_llm.build <span class="hljs-literal">--model</span> <span class="hljs-string">&quot;D:\mlc-llm\qwen&quot;</span> <span class="hljs-literal">--target</span> vulkan <span class="hljs-literal">--quantization</span> q0f16 <span class="hljs-literal">--use-safetensors</span><br></code></pre></td></tr></table></figure><ul><li>等待模型支持:<a href="https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL21sYy1haS9tbGMtbGxtL2lzc3Vlcy8xMzcz" rel="noopener external nofollow noreferrer">Model type qwen not supported</a></li></ul>]]></content>
  230. <summary type="html">&lt;p&gt;&lt;a href=&quot;https://hexo.limour.top/go/#aHR0cHM6Ly9naXRodWIuY29tL21sYy1haS9tbGMtbGxt&quot; rel=&quot;noopener external nofollow noreferrer&quot;&gt;MLC-LLM&lt;/a</summary>
  231. <category term="llama" scheme="https://hexo.limour.top/tags/llama/"/>
  232. </entry>
  233. <entry>
  234. <title>【探索】外科打结法中的等价操作</title>
  235. <link href="https://hexo.limour.top/Equivalent-operations-in-surgical-knot-tying"/>
  236. <id>https://hexo.limour.top/Equivalent-operations-in-surgical-knot-tying</id>
  237. <published>2023-12-02T06:47:05.000Z</published>
  238. <updated>2024-03-19T08:07:10.319Z</updated>
  239. <content type="html"><![CDATA[<p>手术中的止血和缝合,均需要进行结扎,而结扎是否牢固,又与打结有密切关系,结一定要打得牢固,不能松动、滑脱。<br>常用的结扣是方结,结扎后极为牢固,在手术中最常用。而打方结时,手法顺序错误就容易打成假结或滑结。因此这里将探讨基础打结手法的等价性,帮助快速理解不同手法所成结的本质。<br>除不易混淆的外科结外,无论是单手打结还是持钳打结,均由基础动作组合而成,基础动作所成的结都对应纽结理论中的三叶结。三叶结有两种,它们互成镜像,彼此不相同痕,分别称为左手三叶结和右手三叶结。因此无论用哪种手法,最后一定能对应到两种三叶结上。</p><p><img src="https://img.limour.top/2023/12/02/656ad3ee2a544.webp" alt="两种三叶结"></p><p><img src="https://img.limour.top/2023/12/02/656ad41001b48.webp" alt="右手勾法对应右手三叶结"></p><p><img src="https://img.limour.top/2023/12/02/656ad4260ec27.webp" alt="左手勾法对应左手三叶结"></p><p><img src="https://img.limour.top/2023/12/02/656ad43dec1e3.webp" alt="右手掏法对应左手三叶结"></p><p><img src="https://img.limour.top/2023/12/02/656ad43fd2842.webp" alt="左手掏法对应右手三叶结"></p><p><img src="https://img.limour.top/2023/12/02/656ad44069922.webp" alt="镊右手定则法对应右手三叶结"></p><p><img src="https://img.limour.top/2023/12/02/656ad43e8f792.webp" alt="镊左手定则法对应左手三叶结"></p><p>因此,右手勾法、左手掏法、镊右手定则法三者等价;左手勾法、右手掏法、镊左手定则法三者等价。任意组合两种基础打结动作打出<strong>不同</strong>的两种三叶结即可组成一个正确的方结。</p>]]></content>
  240. <summary type="html">&lt;p&gt;手术中的止血和缝合,均需要进行结扎,而结扎是否牢固,又与打结有密切关系,结一定要打得牢固,不能松动、滑脱。&lt;br&gt;
  241. 常用的结扣是方结,结扎后极为牢固,在手术中最常用。而打方结时,手法顺序错误就容易打成假结或滑结。因此这里将探讨基础打结手法的等价性,帮助快速理解不同手法所成结</summary>
  242. <category term="探索" scheme="https://hexo.limour.top/tags/%E6%8E%A2%E7%B4%A2/"/>
  243. </entry>
  244. </feed>