Open main menu
首页
专栏
课程
分类
归档
Chat
Sci-Hub
谷歌学术
Libgen
GitHub镜像
登录/注册
搜索
关闭
Previous
Previous
Next
Next
ChatGLM:本地化搭建大模型实例
sockstack
/
180
/
2023-11-05 12:06:56
<p><span style="color: red; font-size: 18px">ChatGPT 可用网址,仅供交流学习使用,如对您有所帮助,请收藏并推荐给需要的朋友。</span><br><a href="https://ckai.xyz/?sockstack§ion=detail" target="__blank">https://ckai.xyz</a><br><br></p> <div class="notebook-project-preview-content" data-active="true" data-type="notebook"><div class="ai-np"><div class="ai-np-markdown"><div class="ai-np-markdown-cell-content"><h1>1.项目启发</h1> <p>最近ChatGLM-6B清华开源模型发布,之前玩ChatGBT觉得挺好玩,想着能不能自己本地用chatgpt,毕竟某些不可抗力因素使用ChatGBT比较困难,目前申请不了百度文心一言的模型API,因此想自己部署ChatGLM-6B来进行测试,由于本地电脑显存不够(最低都要6GB),所以只能来飞桨平台这里试试了~话不多说让我们进入部署的流程</p> <h2>1.1 硬件需求</h2> <table> <thead> <tr> <th>量化等级</th> <th>最低 GPU 显存</th> </tr> </thead> <tbody> <tr> <td>FP16(无量化)</td> <td>13 GB</td> </tr> <tr> <td>INT8</td> <td>10 GB</td> </tr> <tr> <td>INT4</td> <td>6 GB</td> </tr> </tbody> </table> <h2>1.2 项目地址</h2> <p><strong>Github:<a target="_blank" href="https://github.com/THUDM/ChatGLM-6B">https://github.com/THUDM/ChatGLM-6B</a></strong><br> <strong>Hugging Face Hub(模型地址):<a target="_blank" href="https://huggingface.co/THUDM/chatglm-6b">https://huggingface.co/THUDM/chatglm-6b</a></strong></p> </div></div><div class="ai-np-markdown"><div class="ai-np-markdown-cell-content"><h1>2.部署模型的基本流程(小白向)</h1> <p><strong>2023年4月16日更新:</strong></p> <p><code>1.已将启动所需所有的权重和脚本文件放在data中并且更新成了最新模型,fork后只需解压到同一个文件夹并将其设置成模型启动路径即可(为了减少飞桨保存文件的时间,使用挂载数据效率高)</code></p> <p><code>2.已经更新requirements文件,解决了环境冲突的问题,不需要再单独使用export语句</code></p> <p><code>3.已经更新了cli_demo.py和web_demo.py,启动步骤:(1)解压data文件夹中的chatglm-6b.zip (2)安装所需依赖,已安装可以跳过 (3)在命令行使用脚本启动</code></p> <h2>2.1 从github上下载所需要启动模型的文件</h2> <p>模型启动对应的文件在github上的ChatGLM-6B已经给出,因此需要从github上下载文件夹(文件中下载)</p> <pre><code class="hljs">%<span class="hljs-built_in">cd</span> /home/aistudio/work/ !git <span class="hljs-built_in">clone</span> https://github.com/THUDM/ChatGLM-6B.git </code></pre> <p>当work/路径下有ChatGLM-6B文件就说明下载成功了</p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/b8446b82970a4419a4bf2c2a83323bf58cbaf6a06916484189427a819a7890e2"></p> <p>还需要下载模型文件,可从huggingface.co下载,由于模型文件太大,下载太慢,可先下小文件,之后用清华源下载大模型</p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/08835dbf76c04394a33e0107b14487e2223e0f899baf43fbb09752d81ac8a505"></p> <p><strong>模型文件已经更新到最新版,使用以下命令可在data中生成chatglm6b启动所需的文件</strong></p> <pre><code class="hljs"><span class="hljs-built_in">cd</span> /home/aistudio/data/data203501 unzip chtglm-6b.zip <span class="hljs-built_in">cd</span> </code></pre> </div></div><div class="ai-np-code"><div class="ai-np-code-in">In [ ]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 将启动所需文件解压,后面两个Cell不用运行</span> %cd /home/aistudio/data/data203501 !unzip chatglm<span class="hljs-number">-6</span>b.<span class="hljs-built_in">zip</span> %cd</code></pre></div></div><div class="ai-np-code"><div class="ai-np-code-in">In [ ]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 下载github的启动模型的代码</span> %cd /home/aistudio/work/ !git clone https://github.com/THUDM/ChatGLM<span class="hljs-number">-6</span>B.git</code></pre></div></div><div class="ai-np-code"><div class="ai-np-code-in">In [ ]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 从Hugging Face Hub下载模型小文件,大文件使用清华源下载</span> %cd /home/aistudio/work/ChatGLM<span class="hljs-number">-6</span>B/ GIT_LFS_SKIP_SMUDGE=<span class="hljs-number">1</span> !git lfs install !git clone https://huggingface.co/THUDM/chatglm<span class="hljs-number">-6</span>b</code></pre></div></div><div class="ai-np-markdown"><div class="ai-np-markdown-cell-content"><h2>2.2 安装依赖环境</h2> <p>想要使用ChatGLM-6B需要安装一些依赖环境,这里给出所需要依赖环境所要求的库,需要手动安装,也可以用项目文件下提供的requirement.txt进行快速安装,这里均需要通过命令行进行安装,之前没有成功持久化安装分析原因后估计是飞桨服务器在环境变量加载的时候是按path列表顺序的,而直接append会将环境变量添加到列表最后一个,因此需要将append改为insert插入就可以实现持久化安装</p> <p><strong>为了避免之后的重复安装库,我是选择使用外部依赖库,同时也方便后面的测试(测试可跳转3.1)</strong></p> <pre><code class="hljs">protobuf==3.20.0 transformers==4.27.1 icetk cpm_kernels torch gradio mdtex2html sentencepiece </code></pre> <p><strong>命令行安装</strong></p> <pre><code class="hljs">pip install -r /home/aistudio/work/ChatGLM-6B/requirements.txt </code></pre> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/9999a3c67aca42409e270608d1c1f76199187272255d46e5a5a20642fe3fe0bf"></p> <p><strong>持久化安装(成功安装)</strong></p> <pre><code class="hljs"><span class="hljs-comment">#安装所需要的依赖环境,若环境已安装成功,下面代码可不运行</span> pip install -r /home/aistudio/work/ChatGLM<span class="hljs-number">-6</span>B/requirements.txt -t /home/aistudio/work/external-libraries </code></pre> <p><strong>安装完成可以看到work下的external-libraries外部依赖库是否有所安装的库</strong></p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/475952ed9ded47b9af29772e2d72ed7c669d4fa530514af8b47eb4f5bf844917"></p> </div></div><div class="ai-np-code"><div class="ai-np-code-in">In [ ]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment">#为避免退出studio环境消失,这里使用添加外部库持久化安装</span> !mkdir /home/aistudio/work/external-libraries !pip install -U -r /home/aistudio/work/ChatGLM<span class="hljs-number">-6</span>B/requirements.txt -t /home/aistudio/work/external-libraries <span class="hljs-comment"># 豆瓣源 -i https://pypi.douban.com/simple</span></code></pre></div></div><div class="ai-np-markdown"><div class="ai-np-markdown-cell-content"><h2>2.3 缓存文件的设置</h2> <p>在模型文件中的所设置的缓存路径默认设置都是~/.cache,~ 表示代码主目录,也就是当前登录用户的用户目录,例如<strong>C:/Users/XXX(这里是你的用户名)/</strong>,当本地部署时所有模型文件和配置文件均会放在~/.cache文件夹下,默认C盘会给占用大量的系统盘空间,并且无法很好的管理项目,因此我们要对其进行一个调整,让默认缓存路径修改到我们的模型文件,在飞桨中可不使用这个操作这里为了演示本地化我们修改缓存保存的位置(如果是本地就是你的transformers库环境安装位置)</p> <h3>1. 进入/home/aistudio/external-libraries/transformers/utils/</h3> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/eb20907cf1ef416894a20eb67400da3abcc0384e01c649008df5485f2aabe5d1"></p> <h3>2. 找到hub.py文件并打开,然后修改hf_cache_home变量中的cache位置为你想要放置的cache位置</h3> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/c021ae6a38fc45f1a5f307ffebfb6309b576e99b8158442aad6730dee94bb81f"></p> </div></div><div class="ai-np-code"><div class="ai-np-code-in">In [ ]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 在ChatGLM-6B文件夹下新建缓存文件夹</span> !cd /home/aistudio/work/ChatGLM<span class="hljs-number">-6</span>B && mkdir cache %cd /home/aistudio/work/ChatGLM<span class="hljs-number">-6</span>B</code></pre></div></div><div class="ai-np-markdown"><div class="ai-np-markdown-cell-content"><h2>2.4 预训练模型下载</h2> <p>想要使用模型需要有模型文件,因此需要去下载对应的训练好的模型文件。在github上的ChatGLM-6B给出了模型的一个下载地址 Hugging Face Hub ,但是这个下载实在太慢了,所以我只能去清华给出镜像的官网去下载预训练模型,有需要在本地部署也可以自己去官网下载预训练模型,下面是下载的链接</p> <p><strong>清华镜像:<a target="_blank" href="https://cloud.tsinghua.edu.cn/d/fb9f16d6dc8f482596c2/">https://cloud.tsinghua.edu.cn/d/fb9f16d6dc8f482596c2/</a></strong></p> <p><strong>注:若前面已经从data中复制了模型文件这个Cell可以略过</strong></p> <p>这里需要将预训练模型下载到飞桨Studio中,由于使用wget命令下载失败了,所以我考虑用爬虫的方法去get清华镜像中的的model(爬虫技术这里就不详细介绍了)</p> <p>将模型文件保存到/home/aistudio/work/ChatGLM-6B/chatglm-6b/文件夹下,可用右键快速复制粘贴</p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/13bd4036f55d4b8ca8d1a548f7c52c4ca0600949f0ab40579af5e1637d4f8890"></p> <p>如果我们的文件夹有以下文件就代表模型下载好了(注意要对下模型大小,pytorch开头的文件基本都是1G以上的)</p> <pre><code class="hljs">ice_text.model pytorch_model<span class="hljs-number">-00001</span>-of<span class="hljs-number">-00008.</span><span class="hljs-built_in">bin</span> pytorch_model<span class="hljs-number">-00002</span>-of<span class="hljs-number">-00008.</span><span class="hljs-built_in">bin</span> pytorch_model<span class="hljs-number">-00003</span>-of<span class="hljs-number">-00008.</span><span class="hljs-built_in">bin</span> pytorch_model<span class="hljs-number">-00004</span>-of<span class="hljs-number">-00008.</span><span class="hljs-built_in">bin</span> pytorch_model<span class="hljs-number">-00005</span>-of<span class="hljs-number">-00008.</span><span class="hljs-built_in">bin</span> pytorch_model<span class="hljs-number">-00006</span>-of<span class="hljs-number">-00008.</span><span class="hljs-built_in">bin</span> pytorch_model<span class="hljs-number">-00007</span>-of<span class="hljs-number">-00008.</span><span class="hljs-built_in">bin</span> pytorch_model<span class="hljs-number">-00008</span>-of<span class="hljs-number">-00008.</span><span class="hljs-built_in">bin</span> </code></pre> <p>到这里我们所需要的预训练模型就都准备好了!</p> </div></div><div class="ai-np-code"><div class="ai-np-code-in">In [ ]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 安装爬虫库</span> !pip3 install requests</code></pre></div></div><div class="ai-np-code"><div class="ai-np-code-in">In [1]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 进入模型保存地址</span> %cd /home/aistudio/work/ChatGLM<span class="hljs-number">-6</span>B/chatglm<span class="hljs-number">-6</span>b</code></pre><div class="ai-np-output-wrapper"><pre class="ai-np-output-stream">/home/aistudio/work/ChatGLM-6B/chatglm-6b </pre></div></div></div><div class="ai-np-code"><div class="ai-np-code-in">In [5]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 一开始想用wget命令抓取清华镜像的预训练模型,但一直不成功只能用爬虫方法进行get获取了</span> <span class="hljs-comment"># 获取网页信息</span> <span class="hljs-keyword">import</span> requests url=<span class="hljs-string">'https://cloud.tsinghua.edu.cn/d/fb9f16d6dc8f482596c2/files/?p=%2Fice_text.model&dl=1'</span> save_path=<span class="hljs-string">'ice_text.model'</span> <span class="hljs-comment"># 设置header</span> headers = {<span class="hljs-string">'User-Agent'</span>: <span class="hljs-string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'</span>} <span class="hljs-comment"># 获取文件并写入</span> res = requests.get(url,headers=headers) file1 =<span class="hljs-built_in">open</span>(save_path,<span class="hljs-string">'wb'</span>) file1.write(res.content) file1.close()</code></pre></div></div><div class="ai-np-code"><div class="ai-np-code-in">In [6]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 这里因为解析出的下载的链接只在model-0000?这里有变化,只要在这个位置调整i就可以循环下载,保存文件名类似</span> url1=<span class="hljs-string">'https://cloud.tsinghua.edu.cn/d/fb9f16d6dc8f482596c2/files/?p=%2Fpytorch_model-0000'</span> url2=<span class="hljs-string">'-of-00008.bin&dl=1'</span> save_path1=<span class="hljs-string">'pytorch_model-0000'</span> save_path2=<span class="hljs-string">'-of-00008.bin'</span> headers = {<span class="hljs-string">'User-Agent'</span>: <span class="hljs-string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'</span>} <span class="hljs-comment"># 循环获取models,总共有8个基础模型</span> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">8</span>): url=url1+<span class="hljs-built_in">str</span>(i+<span class="hljs-number">1</span>)+url2 save_path=save_path1+<span class="hljs-built_in">str</span>(i+<span class="hljs-number">1</span>)+save_path2 res = requests.get(url,headers=headers) file1 =<span class="hljs-built_in">open</span>(save_path,<span class="hljs-string">'wb'</span>) file1.write(res.content) file1.close() print(<span class="hljs-string">"第{}个模型下载已完成"</span>.<span class="hljs-built_in">format</span>(i+<span class="hljs-number">1</span>))</code></pre><div class="ai-np-output-wrapper"><pre class="ai-np-output-stream">第1个模型下载已完成 第2个模型下载已完成 第3个模型下载已完成 第4个模型下载已完成 第5个模型下载已完成 第6个模型下载已完成 第7个模型下载已完成 第8个模型下载已完成 </pre></div></div></div><div class="ai-np-markdown"><div class="ai-np-markdown-cell-content"><h2>2.5 对话脚本启动准备</h2> <p>做完以上步骤我们就可以去启动python脚本运行了,ChatGLM-6B下提供了<strong>cli_demo.py</strong>和<strong>web_demo.py</strong>两个文件来启动模型,第一个是使用命令行进行交互,第二个是使用gradio库使用本机服务器进行网页交互,这里只演示使用<strong>cli_demo.py</strong>脚本的启动</p> <h3>1.调整模型文件的启动路径</h3> <p>由于要使用本地模型启动,所以我们需要把从Hugging Face Hub加载改为本地路径加载,在/home/aistudio/work/ChatGLM-6B/下的<strong>cli_demo.py</strong>和<strong>web_demo.py</strong>文件中进行修改</p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/b50fc47a658c4d919e70b52d8480c2d41c9a1077b19d448c884649526980efc4"></p> <p>修改后的地址</p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/956a13ab0f1f469483e4cbf7fa99e3dead20559def4b4ff18b0a2b709683d704"></p> </div></div><div class="ai-np-code"><div class="ai-np-code-in">In [ ]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 启动脚本测试,这里会报错是因为没有添加环境变量的原因</span> !python /home/aistudio/work/ChatGLM<span class="hljs-number">-6</span>B/cli_demo.py</code></pre></div></div><div class="ai-np-markdown"><div class="ai-np-markdown-cell-content"><h3>2.添加环境变量</h3> <p>上面之所以会报错是是因为环境变量未添加</p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/2ae4c56d1b6d4cacaf6e8153ca59969008c79251911344c0a8889c91b4cd32de"></p> <p>这里需要添加以下命令来解决问题</p> <pre><code class="hljs"><span class="hljs-built_in">export</span> LD_LIBRARY_PATH=(你的服务器环境路径):<span class="hljs-variable">$LD_LIBRARY_PATH</span> </code></pre> <p>如果是使用外部库</p> <pre><code class="hljs"><span class="hljs-built_in">export</span> LD_LIBRARY_PATH=(你的外部库环境路径):<span class="hljs-variable">$LD_LIBRARY_PATH</span> </code></pre> </div></div><div class="ai-np-code"><div class="ai-np-code-in">In [12]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 默认环境导入环境变量</span> !export LD_LIBRARY_PATH=<span class="hljs-string">'/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/nvidia/cublas/lib:$LD_LIBRARY_PATH'</span></code></pre></div></div><div class="ai-np-code"><div class="ai-np-code-in">In [1]</div><div class="ai-np-code-main"><pre><code class="hljs"><span class="hljs-comment"># 使用外部库环境导入环境变量</span> !export LD_LIBRARY_PATH=<span class="hljs-string">"/home/aistudio/work/external-libraries/nvidia/cublas/lib:$LD_LIBRARY_PATH"</span></code></pre></div></div><div class="ai-np-markdown"><div class="ai-np-markdown-cell-content"><h1>3.项目启动</h1> <h2>3.1 模型测试</h2> <p>完成以上操作我们就可以使用我们的模型测试了,打开命令行进行交互测试,请使用以下代码进行模型测试,目前使用一些小方法可实现正常对话,这里可能要多尝试几次(已经更新了cli_demo.py和web_demo.py可运行,推荐使用A100含以上的显卡)</p> <p><strong>解压启动文件到模型存放路径并启动</strong></p> <pre><code class="hljs"><span class="hljs-built_in">cd</span> /home/aistudio/data/data203501 unzip chatglm-6b.zip <span class="hljs-built_in">cd</span> </code></pre> <pre><code class="hljs">python /home/aistudio/work/ChatGLM-6B/cli_demo.py </code></pre> <p><strong>模型加载中</strong></p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/081a8077bb064d4eb4f782a6330587beab725625519a4d59bed391673d62bd64"></p> <p><strong>模型测试结果</strong></p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/cdf6340fef2140da8af5ba31c620aea95352e96a116e46d6a00768f590b4242a"></p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/8c7b0d7782624fb4889499b111e2e74e4fe0e7ca7b7e4e37a584b405efdf1a6c"></p> <p><img referrerpolicy="no-referrer" alt="" src="https://ai-studio-static-online.cdn.bcebos.com/8850ce424df4428a86425c8a120aaef5d819f1923dd64fcea6f0eb53e324baf7"></p> </div></div><div class="ai-np-markdown"><div class="ai-np-markdown-cell-content"><h2>3.2 项目总结</h2> <p>飞桨的paddle框架与torch框架会发生冲突,很容易就会因为框架冲突报错,这个我查了很多资料,用了很多办法但目前依然没有好的解决办法😅,由于时间问题后续可能不会再更新项目,只能等飞桨早日更新模型库加入新模型进来。不过整体流程是可在本地实现的,有兴趣和显卡算力的够可自己在本地搭建,这个项目在github上已经基于最开始的模型已经有了一定的优化,不用6G显存也可实现本地运行模型(我的2060还能打😂),其它详情方法请参考:<a target="_blank" href="https://github.com/THUDM/ChatGLM-6B">https://github.com/THUDM/ChatGLM-6B</a> ,以上就是部署的全流程了,希望本项目能对大家有帮助,希望大家能多多给💕</p> <ul> <li>分析了ChatGLM模型文件的整体结构后,我对整体的模型运行逻辑进行了一个分析,后续如果有能力调整的可参考一下</li> </ul> <pre><code class="hljs">models ——config.json <span class="hljs-comment"># 模型的基本信息,包括运行时要调用的py文件和函数,模型的结构参数都放在该json</span> ——configuration_chatglm.py <span class="hljs-comment"># 设置模型的基本参数的py文件</span> ——modeling_chatglm.py <span class="hljs-comment"># 组网程序,也是模型主程序,后续调整环境需要对这个文件进行大幅调整</span> ——quanitization.py <span class="hljs-comment"># 量化程序,主要是为了调整Tensor的精度,默认是bfloat16</span> ——tokenization_chatglm.py <span class="hljs-comment"># 词嵌入程序,主要是为了将语句输入转化为词嵌入向量(token)形式,之后将其送进模型进行推理</span> ——tokenizer_config.json <span class="hljs-comment"># tokenizer的基本设置文件,可查看句子是通过何种方式进行向量化的</span> </code></pre> <ul> <li> <p>在尝试将torch转换paddle发现了挺多问题的,一是这个模型因为一些因素不能直接torch转paddle,我显存和内存都不够尝试Onxx转换也不行,二是模型权重torch的Tensor在转换为paddle的Tensor后直接加载模型后原本模型的一些类函数会失效,导致无法正常运行对话,三是模型组网程序是基于torch的,要转换成paddle后需要对其源文件进行大幅修改,这个工作十分复杂,且测试起来比较麻烦,目前我还无法完全解析</p> </li> <li> <p>这个模型整体是基于torch环境搭建的,并且在运行预训练模型加载后,是调用hub远程代码进行组织本地代码加载的,其组网的modelling_chatglm文件整体均是使用torch环境,要想完全在paddle环境下运行需要对整体文件进行调整,这里我提供一些思路供大家参考</p> <p><code>1.先将模型的参数文件torch的Tensor转换为paddle的Tensor->修改modeling_chatglm.py中的torch代码转换成paddle的等效代码->调整config.json的启动文件</code></p> <p><code>2.将模型加载后使用pytorch2onxx进行转换->再使用onxx2paddle将onxx模型文件转换为paddle的</code></p> </li> </ul> </div></div></div></div>
ChatGLM:本地化搭建大模型实例
作者
sockstack
许可协议
CC BY 4.0
发布于
2023-11-05
修改于
2024-12-22
上一篇:软件:常用 Linux 软件汇总,值得收藏
下一篇:什么是ChatGPT?它为什么这么火?它能做些什么?
尚未登录
登录 / 注册
文章分类
博客重构之路
5
Spring Boot简单入门
4
k8s 入门教程
0
MySQL 知识
1
NSQ 消息队列
0
ThinkPHP5 源码分析
5
使用 Docker 从零开始搭建私人代码仓库
3
日常开发汇总
4
标签列表
springboot
hyperf
swoole
webman
php
多线程
数据结构
docker
k8s
thinkphp
mysql
tailwindcss
flowbite
css
前端