Open main menu
首页
专栏
课程
分类
归档
Chat
Sci-Hub
谷歌学术
Libgen
GitHub镜像
登录/注册
搜索
关闭
Previous
Previous
Next
Next
ChatGPT API接口使用+fine tune微调+prompt介绍
sockstack
/
259
/
2023-11-19 12:00:31
<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> <article class="baidu_pl"><div id="article_content" class="article_content clearfix"> <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css"> <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-25cebea3f9.css"> <div id="content_views" class="markdown_views prism-tomorrow-night"> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg><p></p> <div class="toc"> <h3>目录</h3> <ul> <li>1 接口调用</li> <li><ul> <li>1.1 生成key</li> <li>1.2 接口功能</li> <li><ul> <li>1.2.1 图片生成 (image generation)</li> <li>1.2.2 对话(chat)</li> <li>1.2.3 中文纠错 (Chinese Spelling Correct)</li> <li>1.2.4 关键词提取 (keyword extract)</li> <li>1.2.5 抽取文本向量 (Embedding)</li> <li>1.2.6 微调 (fine tune)</li> </ul></li> </ul></li> <li>2 如何写好prompt</li> <li><ul> <li>2.1分类任务</li> <li>2.2 归纳总结</li> <li>3.3 翻译</li> <li>2.4 API接口多样性控制</li> </ul></li> <li>3 实用资料</li> </ul> </div> <p></p> <h1> <a id="1__2"></a>1 接口调用</h1> <p>我们可以用OpenAI 提供的API接口实现很多NLP的任务,还可以支持生成图像,提取embedding以及finetune的功能。接下来我们来看下具体怎么调用接口。</p> <h2> <a id="11_key_4"></a>1.1 生成key</h2> <p>首先需要从网址:https://platform.openai.com/account/api-keys,<mark>生成我们的API key</mark>:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/07d7a491b5404e2486f723aa8bb435ae.png" alt="在这里插入图片描述"><br> 获得key后我们就可以调用API接口了。目前OpenAI 的 API 服务提供了一个免费的 API 计算单元 (ACU) 的额度,该额度可以用于测试和试用 OpenAI 提供的服务。免费的额度用完后,需要购买额外的 ACU 才能继续使用 OpenAI 的 API 服务。我们可以从Usage和Billing:https://platform.openai.com/account/usage 里去查看我们的免费额度以及进行额度充值:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/273df3ccb1fb4e929a41ea47a216323c.png" alt="在这里插入图片描述"></p> <h2> <a id="12__9"></a>1.2 接口功能</h2> <p>首先我们需要安装openai</p> <pre><code class="prism language-bash">pip <span class="token function">install</span> openai </code></pre> <p>安装好openai以及获得API key后,我们就可以调用接口了,首先我们来看下openai能够提供的模型有什么:</p> <pre><code class="prism language-python"><span class="token keyword">import</span> openai openai<span class="token punctuation">.</span>api_key <span class="token operator">=</span> <span class="token string">"sk-Wljk3BVhN0VieGCwAzEXT3BlbkFJ*******"</span>models <span class="token operator">=</span> openai<span class="token punctuation">.</span>Model<span class="token punctuation">.</span><span class="token builtin">list</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">for</span> model <span class="token keyword">in</span> models<span class="token punctuation">[</span><span class="token string">'data'</span><span class="token punctuation">]</span><span class="token punctuation">:</span><span class="token keyword">print</span><span class="token punctuation">(</span>model<span class="token punctuation">[</span><span class="token string">'id'</span><span class="token punctuation">]</span><span class="token punctuation">)</span> </code></pre> <p>我们可以看出,目前提供的模型有如下:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/84753f154f2f400ab674fc70664e4947.png" alt="在这里插入图片描述"><br> 接下来大概介绍一下我们应该怎样去调用接口,获取我们想要的结果。</p> <h3> <a id="121__image_generation_29"></a>1.2.1 图片生成 (image generation)</h3> <pre><code class="prism language-python"><span class="token keyword">import</span> openai <span class="token keyword">import</span> json<span class="token comment"># 设置API密钥</span> openai<span class="token punctuation">.</span>api_key <span class="token operator">=</span> <span class="token string">"sk-Wljk3BVhN0VieGCwAzEXT3BlbkFJ*******"</span><span class="token keyword">def</span> <span class="token function">image_genaration</span><span class="token punctuation">(</span>prompt<span class="token punctuation">)</span><span class="token punctuation">:</span>response <span class="token operator">=</span> openai<span class="token punctuation">.</span>Image<span class="token punctuation">.</span>create<span class="token punctuation">(</span>prompt<span class="token operator">=</span>prompt<span class="token punctuation">,</span>n<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span>size<span class="token operator">=</span><span class="token string">"1024x1024"</span><span class="token punctuation">)</span>image_url <span class="token operator">=</span> response<span class="token punctuation">[</span><span class="token string">'data'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string">'url'</span><span class="token punctuation">]</span><span class="token keyword">return</span> image_url<span class="token keyword">if</span> __name__<span class="token operator">==</span><span class="token string">'__main__'</span><span class="token punctuation">:</span>prompt<span class="token operator">=</span><span class="token string">'a delicious dessert'</span>result <span class="token operator">=</span> image_genaration<span class="token punctuation">(</span>prompt<span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span></code></pre> <p><mark>prompt=‘a delicious dessert’</mark>, 其中返回url地址,我们将地址复制到浏览器中,打开看到如下图:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/c7766b55102e485baafd5c3cbfba1757.png" alt="在这里插入图片描述"><br> 当<mark>prompt=‘母亲在厨房忙碌着’</mark>,OpenAI返回的效果图如下:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/2e42e3c9341c4d55b0f9471e1e050058.png" alt="在这里插入图片描述"><br> 人物画像细节生成还不够逼真。来试一试中国的古诗词效果,<br> <mark>prompt=‘踏花归去马蹄香’</mark><br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/a6d1aac549f2425cba8799950b579d66.png" alt=""><br> 马蹄上应该画出一些蝴蝶🦋来表达马蹄的花香味啊,不太满意~😞</p> <h3> <a id="122_chat_62"></a>1.2.2 对话(chat)</h3> <p>api接口调用代码如下所示:</p> <pre><code class="prism language-python"><span class="token keyword">import</span> openai <span class="token keyword">import</span> json<span class="token comment"># 设置API密钥</span> openai<span class="token punctuation">.</span>api_key <span class="token operator">=</span> <span class="token string">"sk-Wljk3BVhN0VieGCwAzEXT3BlbkFJ*******"</span> <span class="token keyword">def</span> <span class="token function">chat</span><span class="token punctuation">(</span>prompt<span class="token punctuation">)</span><span class="token punctuation">:</span>response <span class="token operator">=</span> openai<span class="token punctuation">.</span>ChatCompletion<span class="token punctuation">.</span>create<span class="token punctuation">(</span>model<span class="token operator">=</span><span class="token string">"gpt-3.5-turbo"</span><span class="token punctuation">,</span>messages<span class="token operator">=</span><span class="token punctuation">[</span><span class="token punctuation">{<!-- --></span><span class="token string">"role"</span><span class="token punctuation">:</span> <span class="token string">"user"</span><span class="token punctuation">,</span> <span class="token string">"content"</span><span class="token punctuation">:</span>prompt<span class="token punctuation">}</span><span class="token punctuation">]</span> <span class="token punctuation">)</span>answer <span class="token operator">=</span> response<span class="token punctuation">.</span>choices<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>message<span class="token punctuation">.</span>content<span class="token keyword">return</span> answer<span class="token keyword">if</span> __name__<span class="token operator">==</span><span class="token string">'__main__'</span><span class="token punctuation">:</span>prompt<span class="token operator">=</span><span class="token string">'人口最多的国家'</span>result <span class="token operator">=</span> chat<span class="token punctuation">(</span>prompt<span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span> </code></pre> <p>结果如下:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/d785ae08114a42378ac5f00c6701224c.png" alt="在这里插入图片描述"></p> <h3> <a id="123__Chinese_Spelling_Correct_89"></a>1.2.3 中文纠错 (Chinese Spelling Correct)</h3> <p>我们可以通过合理的写prompt,基于问答形式,让gpt-3.5做NLP任务。比如对中文纠错,我们可以这样写prompt,让chagpt能够做纠错NLP任务。如下所示:</p> <pre><code class="prism language-python"><span class="token keyword">def</span> <span class="token function">correct</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>prompt<span class="token operator">=</span><span class="token string">"改正错词输出正确句子:\n\n我在京东电商平台买了苹果耳几和华为体脂称"</span> <span class="token comment">#建议prompt: 改正错词输出正确句子:\n\n input_sentence</span>response <span class="token operator">=</span> openai<span class="token punctuation">.</span>ChatCompletion<span class="token punctuation">.</span>create<span class="token punctuation">(</span>model<span class="token operator">=</span><span class="token string">"gpt-3.5-turbo"</span><span class="token punctuation">,</span>messages<span class="token operator">=</span><span class="token punctuation">[</span><span class="token punctuation">{<!-- --></span><span class="token string">"role"</span><span class="token punctuation">:</span> <span class="token string">"user"</span><span class="token punctuation">,</span> <span class="token string">"content"</span><span class="token punctuation">:</span>prompt<span class="token punctuation">}</span><span class="token punctuation">]</span> <span class="token punctuation">)</span>answer <span class="token operator">=</span> response<span class="token punctuation">.</span>choices<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>message<span class="token punctuation">.</span>content<span class="token keyword">return</span> answer<span class="token keyword">if</span> __name__<span class="token operator">==</span><span class="token string">'__main__'</span><span class="token punctuation">:</span>result <span class="token operator">=</span> correct<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span> </code></pre> <p>结果如下:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/33298cec47894126bb0d2cfc7b2e7801.png" alt="在这里插入图片描述"></p> <h3> <a id="124__keyword_extract_110"></a>1.2.4 关键词提取 (keyword extract)</h3> <pre><code class="prism language-python"><span class="token keyword">def</span> <span class="token function">keyword</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>prompt<span class="token operator">=</span><span class="token string">"对下面内容识别2个关键词,每个词字数不超过3个字:\n\n齐选汽车挂件车内挂饰车载后视镜吊坠高档实心黄铜玉石出入平安保男女 红流苏-玉髓平安扣"</span> <span class="token comment">#建议prompt: 对下面内容识别n个关键词,每个词字数不超过m个字:\n\n input data</span>response <span class="token operator">=</span> openai<span class="token punctuation">.</span>ChatCompletion<span class="token punctuation">.</span>create<span class="token punctuation">(</span>model<span class="token operator">=</span><span class="token string">"gpt-3.5-turbo"</span><span class="token punctuation">,</span>messages<span class="token operator">=</span><span class="token punctuation">[</span><span class="token punctuation">{<!-- --></span><span class="token string">"role"</span><span class="token punctuation">:</span> <span class="token string">"user"</span><span class="token punctuation">,</span> <span class="token string">"content"</span><span class="token punctuation">:</span>prompt<span class="token punctuation">}</span><span class="token punctuation">]</span> <span class="token punctuation">)</span>answer <span class="token operator">=</span> response<span class="token punctuation">.</span>choices<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>message<span class="token punctuation">.</span>content<span class="token keyword">return</span> answer<span class="token keyword">if</span> __name__<span class="token operator">==</span><span class="token string">'__main__'</span><span class="token punctuation">:</span>result <span class="token operator">=</span> keyword<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span> </code></pre> <p><img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/dc573ba3c41242cbb05f3fab9e7e6473.png" alt="在这里插入图片描述"><br> 对于不同的prompt,输出的结果差异也较大。所以对于具体的任务场景,我们需要<mark>尝试不同的prompt, 根据结果的反馈,不断的调整和优化prompt,从而得到更加准确的结果</mark>。</p> <h3> <a id="125__Embedding_130"></a>1.2.5 抽取文本向量 (Embedding)</h3> <pre><code class="prism language-python"><span class="token keyword">def</span> <span class="token function">embedding</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>content <span class="token operator">=</span> <span class="token string">'苹果手机'</span>response <span class="token operator">=</span> openai<span class="token punctuation">.</span>Embedding<span class="token punctuation">.</span>create<span class="token punctuation">(</span>model<span class="token operator">=</span><span class="token string">"text-embedding-ada-002"</span><span class="token punctuation">,</span><span class="token builtin">input</span><span class="token operator">=</span>content <span class="token punctuation">)</span>answer <span class="token operator">=</span> response<span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>embedding<span class="token keyword">return</span> answer<span class="token keyword">if</span> __name__<span class="token operator">==</span><span class="token string">'__main__'</span><span class="token punctuation">:</span>result <span class="token operator">=</span> embedding<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span> </code></pre> <p>得到结果如下:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/a7429435c32c48af9f0898e234bf107c.png" alt="在这里插入图片描述"><br> 是一个1536维度的向量,我们可以基于文本的向量去做很多任务,比如计算<mark>两个向量的余弦值,计算相似性分值</mark>等。</p> <h3> <a id="126__fine_tune_151"></a>1.2.6 微调 (fine tune)</h3> <p>openAI提供了接口可以用我们自己的数据进行fine tune,得到适应我们自己业务场景的新模型。假如我们需要训练一个适应我们自己领域知识的聊天机器人,我们可以按照下面流程来做fine tune。</p> <ul><li><mark>数据准备</mark></li></ul> <p>我们可以先把数据转成csv格式,需提供prompt列和对应的completion列,其中<mark>prompt相当于问题,completion就是对应的答案</mark>,如下是我们要用来fine tune模型的result.csv训练样本内容显示:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/07c3b81b84434c52abdeb35db6b362b1.png" alt="在这里插入图片描述"><br> 然后我们可以用openAI提供的数据处理工具对数据转成json格式的文件</p> <pre><code class="prism language-powershell">openai tools fine_tunes<span class="token punctuation">.</span>prepare_data <span class="token operator">-</span>f result<span class="token punctuation">.</span>csv </code></pre> <p>执行完后,我们会得到一个对应的json文件:result_prepared.jsonl</p> <ul><li> <mark>模型微调训练</mark><br> 接下来我们就可以用已有的模型 (ada, babbage, curie, davinci) 进行fine tune,官方给出的具体可以用来做微调的模型主要如下:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/b3fae9c1e7234cf3999531ff310259e2.png" alt="在这里插入图片描述"><br> 首先需要指定我们自己的API key:</li></ul> <pre><code class="prism language-powershell">export OPENAI_API_KEY=<span class="token string">"sk-Wljk3BVhN0VieGCwAzEX*********"</span> </code></pre> <p>然后开始训练:</p> <pre><code class="prism language-powershell">openai api fine_tunes<span class="token punctuation">.</span>create <span class="token operator">-</span>t result_prepared<span class="token punctuation">.</span>jsonl <span class="token operator">-</span>m ada </code></pre> <p>在这里用我们<mark>自己的数据result_prepared.jsonl,基于base model: ada模型提交fine tune任务</mark>。提交后会返回给我们一个JOB ID,通过这个job id我们可以跟进模型在远程服务器训练情况:</p> <pre><code class="prism language-powershell"> openai api fine_tunes<span class="token punctuation">.</span>follow <span class="token operator">-</span>i <span class="token function">ft</span><span class="token operator">-</span>sWKDNnTmUyOGEdpvbAOvEaZt </code></pre> <p>我们可以看到结果如下:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/6eac7070d5b64c6cb64266b55631166a.png" alt="在这里插入图片描述"><br> 可以看到我们的模型训练好了模型名称叫做:ada:ft-personal-2023-03-27-03-24-09,然后我们就可以试用我们训练好的模型看效果了,测试如下:</p> <pre><code class="prism language-powershell">openai api completions<span class="token punctuation">.</span>create <span class="token operator">-</span>m ada:<span class="token function">ft</span><span class="token operator">-</span>personal-2023-03-27-03-24-09 <span class="token operator">-</span>p <YOUR_PROMPT> </code></pre> <p>其中<YOUR_PROMPT>写入我们要测试的问题就好。</p> <p>现在我们可以去远程服务器上查看下我们fine tune好的模型是否已经有了:</p> <pre><code class="prism language-powershell">models = openai<span class="token punctuation">.</span>Model<span class="token punctuation">.</span>list<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <p>发现有了刚刚fine tune的模型:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/c1ae2b5a7dd34f6b8f4359ca78d3d47f.png" alt="在这里插入图片描述"><br> 对于分类,实体识别等任务,OPNAI官网也提供了如何做处理数据,让模型做fine tune,详情可以参考官网https://platform.openai.com/docs/introduction/overview</p> <h1> <a id="2_prompt_200"></a>2 如何写好prompt</h1> <p><mark>prompt如何表达,对于chatgpt返回的答案会差异很大</mark>,通过prompt正确的表达问题,chatgpt才会返回更合适的结果。通过自己这些天的尝试以及官网给的提示,感受就是<mark>在写prompt时候,可以通过说明,例子,限制条件,修饰词等具体表达问题</mark>,这样chatgpt会给出更加精准的答案。接下来,我们对几种常见的任务,prompt应用如何写。</p> <h2> <a id="21_203"></a>2.1分类任务</h2> <p>我们可以对prompt这么构造:<br> <mark>判断content属于A,B,C,D哪一种分类<br> content: detail<br> 分类:</mark></p> <p>对应的查询结果如下:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/512a5868a57f4076b4649a4843a0d4ad.png" alt="在这里插入图片描述"></p> <h2> <a id="22__211"></a>2.2 归纳总结</h2> <p>提供了非常强大能力,能够基于学到的广泛知识,给出问题解决方案,合理的建议,实施步骤,商业计划,人物描写等等。所以我们可以合理写prompt,更有意思的答案。<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/3e89d064e71c4b4aa8e602e5532e1024.png" alt="在这里插入图片描述"></p> <p>哈哈,看起来不够大胆,于是<mark>进一步发问</mark>:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/f6f572100ed74889bdad8178574f3752.png" alt="在这里插入图片描述"><br> 给出的这些答案果然更加激动人心。</p> <h2> <a id="33__219"></a>3.3 翻译</h2> <p>我们可以将一种语言翻译成我们大多数其他语言。对于翻译任务,我们只需要写prompt表达我们的意愿就是:<br> <mark>将下面内容翻译成英语,日语,德语<br> content</mark><br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/3ac5f613a44c4fa3b327fc673e8e0085.png" alt="在这里插入图片描述"></p> <h2> <a id="24_API_224"></a>2.4 API接口多样性控制</h2> <p>在调用API接口的时候,我们可以通过设置两个参数=='temperature’和’top_p’<mark>来控制生成文本的</mark>多样性和可控度==。<mark>当temperature较高时,生成的文本会更加随机和多样化,而当temperature较低时,生成的文本会更加保守和可控</mark>。top_p参数用于控制生成文本的可控度,它会限制模型生成文本时可以选择的token的数量。具体来说,<mark>当top_p越低时,模型只考虑概率分布中累计概率最高的一部分token,而忽略其他低概率的token</mark>。这样一来,生成的文本就更加可控,因为只有那些最可能的token才会被考虑。而当top_p越高的时候,生成的文本可能会更加灵活和多样,因为模型会考虑更多的低概率token。每次调用的时候,我们可以设置这两个参数:<br> <img referrerpolicy="no-referrer" src="https://img-blog.csdnimg.cn/62f782da9cd44e8da7d3d17f86d3c2c3.png" alt="在这里插入图片描述"></p> <h1> <a id="3__227"></a>3 实用资料</h1> <p>大模型训练平台:https://github.com/hpcaitech/ColossalAI<br> 相关资料:中文精选资源清单</p> </div> <link href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/markdown_views-0407448025.css" rel="stylesheet"> <link href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/style-c216769e99.css" rel="stylesheet"> </div> <div id="treeSkill"></div> </article>
ChatGPT API接口使用+fine tune微调+prompt介绍
作者
sockstack
许可协议
CC BY 4.0
发布于
2023-11-19
修改于
2024-12-21
上一篇:软件:常用 Linux 软件汇总,值得收藏
下一篇:一文谈谈文心一言对比ChatGPT4.0的差距
尚未登录
登录 / 注册
文章分类
博客重构之路
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
前端