├── LICENSE ├── README.md ├── README_zh.md ├── demo.png ├── demo.py ├── finetune ├── README.md ├── README_zh.md ├── data.json ├── finetune.py └── finetune.sh ├── models └── readme.md ├── requirements.txt ├── sponsor.jpg ├── webdemo.py ├── webdemo1.png └── webdemo2.png /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [切换到中文版本](README_zh.md) 2 | 3 | [Switch to English Version](README.md) 4 | 5 | # Noname AI 6 | 7 | Projects related to Noname AI/Noname AI, involving AI programs aimed at generating Noname skill codes by inputting skill effects. 8 | 9 | [modelscope Online Experience](https://www.modelscope.cn/studios/huskyhong/nonameai) 10 | 11 | Due to limited computing power, the online experience version is only a lightweight CPU version with limited precision. If needed, please choose the GPU version or full version for inference. 12 | Fine-tuned from QWen. 13 | 14 | ## Configuration Requirements 15 | 16 | To better meet usage requirements, please try to meet the following requirements: 17 | 18 | - Computer (required) 19 | - Hard disk storage space of 20G or more (required) 20 | - If using the full non-quantized version/GPU version lazy one-click package, for computers with NVIDIA graphics cards, GPU inference is used, requiring half of the graphics memory + computer physical memory (physical memory does not include virtual memory) >= 16G 21 | - If using the full non-quantized version/CPU version lazy one-click package, CPU inference is used, requiring memory (including virtual memory) to be as close as possible to >= 32G for computers without graphics cards 22 | - If using the lightweight version/GPU version lightweight lazy one-click package, for computers with NVIDIA graphics cards, GPU inference is used, requiring half of the graphics memory + computer physical memory (physical memory does not include virtual memory) >= 4G 23 | - If using the lightweight version/CPU version lightweight lazy one-click package, CPU inference is used, requiring memory (including virtual memory) to be as close as possible to >= 12G for computers without graphics cards 24 | 25 | ## Usage 26 | 27 | ### Full Model Method 28 | 29 | 1. Install Python and the corresponding Python compiler. 30 | - Note: Python compatible versions are 3.8, 3.9, 3.10, 3.11. Please do not install versions that are too high or too low. 31 | 2. Enter the following command in the terminal to install the required environment: 32 | 33 | ```bash 34 | pip install -r requirements.txt 35 | ``` 36 | 37 | 3. Run the program using the following Python code. The model will be automatically downloaded. 38 | The execution method for the v3.x model is as follows: 39 | ```python 40 | from transformers import AutoModelForCausalLM, AutoTokenizer 41 | 42 | model_name = "huskyhong/noname-ai-v3.0" 43 | 44 | model = AutoModelForCausalLM.from_pretrained( 45 | model_name, 46 | torch_dtype="auto", 47 | device_map="auto" 48 | ) 49 | tokenizer = AutoTokenizer.from_pretrained(model_name) 50 | 51 | prompt = "请帮我用JavaScript编写一个无名杀游戏的技能,技能效果如下:你使用杀造成的伤害+1" 52 | # prompt = "请帮我用JavaScript编写一张无名杀游戏的卡牌,卡牌效果如下:xxx" 53 | messages = [ 54 | {"role": "system", "content": "你是由B站up主AKA臭脸臭羊驼训练得到的无名杀AI,旨在帮助用户编写无名杀技能或卡牌代码."}, 55 | {"role": "user", "content": prompt} 56 | ] 57 | text = tokenizer.apply_chat_template( 58 | messages, 59 | tokenize=False, 60 | add_generation_prompt=True 61 | ) 62 | model_inputs = tokenizer([text], return_tensors="pt").to(model.device) 63 | 64 | generated_ids = model.generate( 65 | **model_inputs, 66 | max_new_tokens=512 67 | ) 68 | generated_ids = [ 69 | output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) 70 | ] 71 | 72 | response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] 73 | print(response) 74 | ``` 75 | 76 | The execution method for the v2.x 和 v1.x model is as follows: 77 | ```python 78 | from transformers import AutoModelForCausalLM, AutoTokenizer 79 | from transformers.generation import GenerationConfig 80 | tokenizer = AutoTokenizer.from_pretrained("huskyhong/noname-ai-v2_5", trust_remote_code=True) 81 | model = AutoModelForCausalLM.from_pretrained("huskyhong/noname-ai-v2_5", device_map="auto", trust_remote_code=True).eval() # Load the model using GPU 82 | # model = AutoModelForCausalLM.from_pretrained("huskyhong/noname-ai-v2_5", device_map="cpu", trust_remote_code=True).eval() # Load the model using CPU 83 | 5model.generation_config = GenerationConfig.from_pretrained("huskyhong/noname-ai-v2_5", trust_remote_code=True) # You can specify different generation lengths, top_p, 和 other related hyperparameters 84 | # For the first generation model, replace "huskyhong/noname-ai-v2_5" with "huskyhong/noname-ai-v1". For lightweight version v2.5 model, replace "huskyhong/noname-ai-v2_5" with "huskyhong/noname-ai-v2_5-light" 85 | 86 | prompt = "请帮我编写一个技能,技能效果如下:" + input("请输入技能效果:") 87 | response, history = model.chat(tokenizer, prompt, history = []) 88 | print(response) 89 | 90 | prompt = "请帮我编写一张卡牌,卡牌效果如下::" + input("请输入卡牌效果:") 91 | response, history = model.chat(tokenizer, prompt, history = []) 92 | print(response) 93 | ``` 94 | Alternatively, you can use Hugging Face's pipeline for inference. 95 | ```python 96 | from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM, GenerationConfig 97 | generator = pipeline( 98 | "text-generation", 99 | model="huskyhong/noname-ai-v2_5", 100 | tokenizer="huskyhong/noname-ai-v2_5", 101 | device=0, # Choose GPU device. If you want to use CPU, you can set device=-1 102 | trust_remote_code=True 103 | ) 104 | 105 | prompt = "请帮我编写一个技能,技能效果如下:" + input("请输入技能效果:") 106 | response = generator(prompt, max_length=50, top_p=0.95) # You can adjust parameters such as generation length, top_p as needed 107 | print(response[0]['generated_text']) 108 | 109 | prompt = "请帮我编写一张卡牌,卡牌效果如下:" + input("请输入卡牌效果:") 110 | response = generator(prompt, max_length=50, top_p=0.95) # You can adjust parameters such as generation length, top_p as needed 111 | print(response[0]['generated_text']) 112 | ``` 113 | 114 | 4. If automatic downloading fails, you can manually download the model files and modify "huskyhong/noname-ai-v2" to the corresponding location in the code. 115 | Download links for the third-generation model: 116 | - [v3.0 Hugging Face address (full version)](https://huggingface.co/huskyhong/noname-ai-v3.0) 117 | - [v3.0 Hugging Face address (mediumweight version)](https://huggingface.co/huskyhong/noname-ai-v3.0-medium) 118 | - [v3.0 Hugging Face address (lightweight version)](https://huggingface.co/huskyhong/noname-ai-v3.0-light) 119 | - [v3.0 Hugging Face address (miniweight version)](https://huggingface.co/huskyhong/noname-ai-v3.0-mini) 120 | - [Baidu Netdisk address](https://pan.baidu.com/s/1zIcRZtQv5oIdu7_abie9Vw?pwd=6666) Baidu Netdisk extraction code: 6666 121 | Download links for the second-generation model: 122 | - [v2.5 Hugging Face address (full version)](https://huggingface.co/huskyhong/noname-ai-v2_5) 123 | - [v2.5 Hugging Face address (lightweight version)](https://huggingface.co/huskyhong/noname-ai-v2_5-light) 124 | - [Baidu Netdisk address](https://pan.baidu.com/s/1m9RfGqnuQbRYROE_UzuG-Q?pwd=6666) Baidu Netdisk extraction code: 6666 125 | Download links for the first-generation model: 126 | - [Hugging Face address](https://huggingface.co/huskyhong/noname-ai-v1) 127 | - [Baidu Netdisk address](https://pan.baidu.com/s/1Ox471XuHF_gJbcPPnSZe7g?pwd=6666) Baidu Netdisk extraction code: 6666 128 | Remember to choose whether to load the model using GPU or CPU, and replace `your_model_name` with your actual model path. 129 | 130 | ## Lazy One-Click Package 131 | 132 | - One-click installation, no worries. 133 | - Please choose the appropriate lazy one-click package according to your own configuration. 134 | - [Lazy One-Click Package Baidu Netdisk Download Address (Updated to v3.0)](https://pan.baidu.com/s/1zIcRZtQv5oIdu7_abie9Vw?pwd=6666) Baidu Netdisk extraction code: 6666 135 | - [Lazy One-Click Package 123 Netdisk Download Address (Updated to v2.5)](https://www.123pan.com/s/lOcnjv-pnOG3.html) 123 Netdisk extraction code: 6666 136 | - Please pay attention to the version time of the lazy one-click package to ensure that the version is the latest! 137 | - Lazy package related videos 138 | - [Comparison of Effects of Lazy Package v2.5](https://www.bilibili.com/video/BV1KKY4e8EaC/) 139 | 140 | ## Web Version/Server Deployment 141 | - Install Python 142 | - Install dependencies 143 | ```bash 144 | pip install -r requirements.txt 145 | ``` 146 | - Install Streamlit 147 | ```bash 148 | pip install streamlit 149 | ``` 150 | - Allow port 8501 on the server (can also be changed to others, corresponding to webdemo.py file) 151 | - Run webdemo 152 | ```bash 153 | streamlit run webdemo.py 154 | ``` 155 | ## Training 156 | Training requires installing new dependencies: 157 | ```python 158 | pip install peft deepspeed 159 | ``` 160 | Clone the project和download the v2.3 version of the model files, taking the lightweight version as an example: 161 | ```bash 162 | git lfs install 163 | git clone https://github.com/204313508/noname_llm.git 164 | git clone https://huggingface.co/huskyhong/noname-ai-v2_3-light 165 | cd noname_llm/finetune 166 | ``` 167 | Modify the parameters required for training in the finetune script, such as model and dataset locations, then enter the following command to start training: 168 | ```bash 169 | bash finetune.sh 170 | ``` 171 | Please refer to the [Fine-tuning Guide](./finetune/README.md) for detailed steps. 172 | 173 | ## Web Version/Server Example 174 | ![webdemo1](./webdemo1.png) 175 | ![webdemo2](./webdemo2.png) 176 | 177 | ## Notes 178 | 179 | - AI generation is subject to uncontrollable factors, and the generated code does not guarantee 100% effectiveness. Bugs, redundant code, or additional special characters may still occur and require manual modification. 180 | - (Important) Follow AI specifications. This AI model is for learning and communication purposes only. Please do not use it for illegal or commercial purposes. The purpose of releasing this model is to encourage better learning and communication, and all related information involved in the model is public. I bear no responsibility for malicious use of this AI model. 181 | 182 | ## Other Content 183 | 184 | If you have any related questions, please raise them in the official GitHub issue. 185 | 186 | ## Demo Images 187 | These demo images are based on version 2.3 release. 188 | ![demo](./demo.png) 189 | 190 | 191 | ## Sponsorship 192 | - Shamelessly begging for sponsorship 193 | ![sponsor](./sponsor.jpg) 194 | -------------------------------------------------------------------------------- /README_zh.md: -------------------------------------------------------------------------------- 1 | [切换到中文版本](README_zh.md) 2 | 3 | [Switch to English Version](README.md) 4 | # 无名杀AI 5 | 6 | 无名杀ai/无名杀AI相关项目,该项目涉及AI程序,旨在通过输入技能效果,生成无名杀技能代码。 7 | [modelscope(魔搭社区)在线体验](https://www.modelscope.cn/studios/huskyhong/nonameai) 8 | 因为算力有限,在线体验版本仅为轻量cpu版,精度有限,如有需求请选择gpu版、完整版进行推理 9 | finetuned from QWen 10 | ## 配置要求 11 | 12 | 为了更好地满足使用需求,请尽可能满足以下要求: 13 | 14 | - 电脑(必须) 15 | - 硬盘存储空间20G以上(必须) 16 | - 若使用完整非量化版本/gpu版懒人一键包,对于具有 NVIDIA 显卡的电脑,采用gpu推理,要求显存 + 电脑物理内存(物理内存不包含虚拟内存)的一半 >= 16G 17 | - 若使用完整非量化版本/cpu版懒人一键包,采用cpu方式推理,对于无显卡的电脑,要求内存(可包含虚拟内存)尽可能满足 >= 32G 18 | - 若使用轻量版/gpu版轻量版懒人一键包,对于具有 NVIDIA 显卡的电脑,采用gpu推理,要求显存 + 电脑物理内存(物理内存不包含虚拟内存)的一半 >= 4G 19 | - 若使用轻量版/cpu版轻量版懒人一键包,采用cpu方式推理,对于无显卡的电脑,要求内存(可包含虚拟内存)尽可能满足 >= 12G 20 | 21 | ## 使用方法 22 | ### 完整模型法 23 | 1. 安装 Python 以及相应的 Python 编译器 24 | - 注意:python适配版本为3.8,3.9,3.10,3.11,请勿安装过高或过低版本 25 | 2. 在终端(命令行)中输入以下命令安装依赖环境: 26 | 27 | ```bash 28 | pip install -r requirements.txt 29 | ``` 30 | 3. 采用以下python代码运行程序,模型将会自动下载,v3.x模型代码运行方式如下: 31 | ```python 32 | from transformers import AutoModelForCausalLM, AutoTokenizer 33 | 34 | model_name = "huskyhong/noname-ai-v3.0" 35 | 36 | model = AutoModelForCausalLM.from_pretrained( 37 | model_name, 38 | torch_dtype="auto", 39 | device_map="auto" 40 | ) 41 | tokenizer = AutoTokenizer.from_pretrained(model_name) 42 | 43 | prompt = "请帮我用JavaScript编写一个无名杀游戏的技能,技能效果如下:你使用杀造成的伤害+1" 44 | # prompt = "请帮我用JavaScript编写一张无名杀游戏的卡牌,卡牌效果如下:xxx" 45 | messages = [ 46 | {"role": "system", "content": "你是由B站up主AKA臭脸臭羊驼训练得到的无名杀AI,旨在帮助用户编写无名杀技能或卡牌代码."}, 47 | {"role": "user", "content": prompt} 48 | ] 49 | text = tokenizer.apply_chat_template( 50 | messages, 51 | tokenize=False, 52 | add_generation_prompt=True 53 | ) 54 | model_inputs = tokenizer([text], return_tensors="pt").to(model.device) 55 | 56 | generated_ids = model.generate( 57 | **model_inputs, 58 | max_new_tokens=512 59 | ) 60 | generated_ids = [ 61 | output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) 62 | ] 63 | 64 | response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] 65 | print(response) 66 | ``` 67 | 68 | v2.x,v1.x代码运行方式如下 69 | 70 | ```python 71 | from transformers import AutoModelForCausalLM, AutoTokenizer 72 | from transformers.generation import GenerationConfig 73 | tokenizer = AutoTokenizer.from_pretrained("huskyhong/noname-ai-v2_5", trust_remote_code=True) 74 | model = AutoModelForCausalLM.from_pretrained("huskyhong/noname-ai-v2_5", device_map="auto", trust_remote_code=True).eval() # 采用gpu加载模型 75 | # model = AutoModelForCausalLM.from_pretrained("huskyhong/noname-ai-v2_5", device_map="cpu", trust_remote_code=True).eval() # 采用cpu加载模型 76 | model.generation_config = GenerationConfig.from_pretrained("huskyhong/noname-ai-v2_5", trust_remote_code=True) # 可指定不同的生成长度、top_p等相关超参 77 | # 第一代模型请将huskyhong/noname-ai-v2_5改为huskyhong/noname-ai-v1,轻量版v2.5模型请将huskyhong/noname-ai-v2_5改为huskyhong/noname-ai-v2_5-light 78 | 79 | prompt = "请帮我编写一个技能,技能效果如下:" + input("请输入技能效果:") 80 | response, history = model.chat(tokenizer, prompt, history = []) 81 | print(response) 82 | 83 | prompt = "请帮我编写一张卡牌,卡牌效果如下::" + input("请输入卡牌效果:") 84 | response, history = model.chat(tokenizer, prompt, history = []) 85 | print(response) 86 | ``` 87 | 也可以采用huggingface的pipeline进行推理 88 | ```python 89 | from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM, GenerationConfig 90 | generator = pipeline( 91 | "text-generation", 92 | model="huskyhong/noname-ai-v2_5", 93 | tokenizer="huskyhong/noname-ai-v2_5", 94 | device=0, # 选择GPU设备,如果要使用CPU,可以设置device=-1 95 | trust_remote_code=True 96 | ) 97 | 98 | prompt = "请帮我编写一个技能,技能效果如下:" + input("请输入技能效果:") 99 | response = generator(prompt, max_length=50, top_p=0.95) # 可根据需要调整生成长度、top_p等超参数) 100 | print(response[0]['generated_text']) 101 | 102 | prompt = "请帮我编写一张卡牌,卡牌效果如下:" + input("请输入卡牌效果:") 103 | response = generator(prompt, max_length=50, top_p=0.95) # 可根据需要调整生成长度、top_p等超参数 104 | print(response[0]['generated_text']) 105 | ``` 106 | 107 | 4. 如果自动下载出错,可以手动下载模型文件,同时修改代码中的"huskyhong/noname-ai-v2"为相应位置 108 | 第三代模型下载地址: 109 | - [v3.0版本huggingface地址(完整版)](https://huggingface.co/huskyhong/noname-ai-v2_5) 110 | - [v3.0版本huggingface地址(普通版)](https://huggingface.co/huskyhong/noname-ai-v2_5-medium) 111 | - [v3.0版本huggingface地址(轻量版)](https://huggingface.co/huskyhong/noname-ai-v2_5-light) 112 | - [v3.0版本huggingface地址(迷你版)](https://huggingface.co/huskyhong/noname-ai-v2_5-mini) 113 | - [百度网盘地址](https://pan.baidu.com/s/1zIcRZtQv5oIdu7_abie9Vw?pwd=6666) 百度网盘提取码:6666 114 | 第二代模型下载地址: 115 | - [v2.5版本huggingface地址(完整版)](https://huggingface.co/huskyhong/noname-ai-v2_5) 116 | - [v2.5版本huggingface地址(轻量版)](https://huggingface.co/huskyhong/noname-ai-v2_5-light) 117 | - [百度网盘地址](https://pan.baidu.com/s/1m9RfGqnuQbRYROE_UzuG-Q?pwd=6666) 百度网盘提取码:6666 118 | 第一代模型下载地址: 119 | - [huggingface地址](https://huggingface.co/huskyhong/noname-ai-v1) 120 | - [百度网盘地址](https://pan.baidu.com/s/1Ox471XuHF_gJbcPPnSZe7g?pwd=6666) 百度网盘提取码:6666 121 | 记得选择采用gpu加载模型还是cpu加载模型,然后把 `your_model_name` 替换为你实际的模型路径。 122 | 123 | ## 懒人一键包 124 | - 一键安装,无需烦恼 125 | - 请根据自身配置选择合适的懒人一键包 126 | - [懒人一键包百度网盘下载地址(已更新v3.0)](https://pan.baidu.com/s/1zIcRZtQv5oIdu7_abie9Vw?pwd=6666) 百度网盘提取码:6666 127 | - [懒人一键包123网盘下载地址(已更新v2.5)](https://www.123pan.com/s/lOcnjv-pnOG3.html) 123网盘提取码:6666 128 | - 请注意懒人一键包版本时间,确保版本为最新版! 129 | - 懒人包相关视频 130 | - [懒人包v2.5版效果对比]([https://www.bilibili.com/video/BV1KKY4e8EaC] 131 | ## 网页版/服务器部署 132 | - 安装 Python 133 | - 安装依赖环境 134 | ```bash 135 | pip install -r requirements.txt 136 | ``` 137 | - 安装streamlit 138 | ```bash 139 | pip install streamlit 140 | ``` 141 | - 服务器放行8501端口(也可自行改成其他,需要和webdemo.py文件中对应) 142 | - 运行webdemo 143 | ```bash 144 | streamlit run webdemo.py 145 | ``` 146 | 147 | ## 训练/微调 148 | 训练/微调需要安装新的依赖项 149 | ```python 150 | pip install peft deepspeed 151 | ``` 152 | 克隆该项目,并下载v2.3版本的模型文件,以轻量版为例: 153 | ```bash 154 | git lfs install 155 | git clone https://github.com/204313508/noname_llm.git 156 | git clone https://huggingface.co/huskyhong/noname-ai-v2_3-light 157 | cd noname_llm/finetune 158 | ``` 159 | 修改finetune.sh中训练所需参数,模型、数据集位置等信息,之后输入以下命令开始训练 160 | ```bash 161 | bash finetune.sh 162 | ``` 163 | 详细步骤请参考[微调说明](./finetune/README.md) 164 | 165 | ## 网页版/服务器示例 166 | ![webdemo1](./webdemo1.png) 167 | ![webdemo2](./webdemo2.png) 168 | ## 注意事项 169 | 170 | - AI生成受不可控因素影响,生成的代码不保证100%有效,仍可能出现bug、冗余代码或额外特殊符号等,需要人工修改。 171 | - (重要)遵循AI规范,本AI模型仅用于学习交流使用,请勿用于不法用途以及商业用途。本人发布该模型初衷是希望大家更好地学习和交流,模型涉及的所有相关信息都是公开的。对于恶意使用本AI模型的,本人概不负责。 172 | 173 | ## 其他内容 174 | 175 | 如果有相关问题,请在GitHub官方的issue中提出。 176 | 177 | ## 演示图片 178 | 该演示图片基于v3.x启动器发布 179 | ![demo1](./demo.png) 180 | 181 | ## 赞助 182 | - 厚颜无耻的求一个赞助 183 | ![sponsor](./sponsor.jpg) 184 | -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/204313508/noname_llm/a98f60da7a45ee0b52bd2c97c2b34ba52d0c18d4/demo.png -------------------------------------------------------------------------------- /demo.py: -------------------------------------------------------------------------------- 1 | from transformers import AutoModelForCausalLM, AutoTokenizer 2 | 3 | model_name = "huskyhong/noname-ai-v3.0" 4 | 5 | model = AutoModelForCausalLM.from_pretrained( 6 | model_name, 7 | torch_dtype="auto", 8 | device_map="auto" 9 | ) 10 | tokenizer = AutoTokenizer.from_pretrained(model_name) 11 | 12 | prompt = "请帮我用JavaScript编写一个无名杀游戏的技能,技能效果如下:你使用杀造成的伤害+1" 13 | # prompt = "请帮我用JavaScript编写一张无名杀游戏的卡牌,卡牌效果如下:xxx" 14 | messages = [ 15 | {"role": "system", "content": "你是由B站up主AKA臭脸臭羊驼训练得到的无名杀AI,旨在帮助用户编写无名杀技能或卡牌代码."}, 16 | {"role": "user", "content": prompt} 17 | ] 18 | text = tokenizer.apply_chat_template( 19 | messages, 20 | tokenize=False, 21 | add_generation_prompt=True 22 | ) 23 | model_inputs = tokenizer([text], return_tensors="pt").to(model.device) 24 | 25 | generated_ids = model.generate( 26 | **model_inputs, 27 | max_new_tokens=512 28 | ) 29 | generated_ids = [ 30 | output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) 31 | ] 32 | 33 | response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] 34 | print(response) -------------------------------------------------------------------------------- /finetune/README.md: -------------------------------------------------------------------------------- 1 | [Switch to Chinese Version](README_zh.md) 2 | 3 | # Noname AI Model Fine-tuning 4 | 5 | ## Introduction 6 | 7 | This repository contains scripts for fine-tuning the Noname AI model on custom datasets. Before starting the fine-tuning process, make sure you have installed the necessary dependencies and obtained the required model and dataset files. 8 | 9 | ## Dependencies 10 | 11 | Run the following command to install the required dependencies: 12 | 13 | ```bash 14 | pip install peft deepspeed 15 | ``` 16 | 17 | ## Setup 18 | 19 | 1. Clone this repository: 20 | 21 | ```bash 22 | git clone https://github.com/204313508/noname_llm.git 23 | cd noname_llm/finetune 24 | ``` 25 | 26 | 2. Clone the model files of version v2.3 from Hugging Face: 27 | 28 | ```bash 29 | git lfs install 30 | git clone https://huggingface.co/huskyhong/noname-ai-v2_3-light 31 | ``` 32 | 33 | 3. Set environment variables and adjust the parameters in the training script (`finetune.sh`) according to your requirements: 34 | 35 | ```bash 36 | export CUDA_DEVICE_MAX_CONNECTIONS=1 37 | export CUDA_VISIBLE_DEVICES=0 38 | 39 | MODEL="/tmp/pretrainmodel/nonameai" 40 | DATA="/tmp/code/data.json" 41 | ``` 42 | 43 | ## Dataset Format 44 | 45 | The dataset is stored in JSON format, as shown below: 46 | 47 | ```json 48 | [ 49 | { 50 | "id": "identity_0", 51 | "conversations": [ 52 | { 53 | "from": "user", 54 | "value": "Please help me write a skill, the skill effect is as follows: your skill effect description" 55 | }, 56 | { 57 | "from": "assistant", 58 | "value": "Your skill code" 59 | } 60 | ] 61 | }, 62 | { 63 | "id": "identity_1", 64 | "conversations": [ 65 | { 66 | "from": "user", 67 | "value": "Please help me write a skill, the skill effect is as follows: your skill effect description" 68 | }, 69 | { 70 | "from": "assistant", 71 | "value": "Your skill code" 72 | } 73 | ] 74 | }, 75 | ... 76 | ] 77 | ``` 78 | 79 | ## Parameter Modification Instructions 80 | 81 | In the `finetune.py` script, you can adjust the following parameters according to your task requirements: 82 | 83 | - `--model_name_or_path`: Specify the path or name of the model. 84 | - `--data_path`: Specify the path of the dataset. 85 | - `--num_train_epochs`: Specify the number of training epochs. 86 | - `--per_device_train_batch_size`: Specify the training batch size per device. 87 | - `--per_device_eval_batch_size`: Specify the evaluation batch size per device. 88 | - `--max_steps`: Specify the maximum number of training steps. 89 | - `--learning_rate`: Specify the learning rate. 90 | - `--weight_decay`: Specify the weight decay. 91 | 92 | ## Fine-tuning 93 | 94 | Run the following command to start the fine-tuning process: 95 | 96 | ```bash 97 | bash finetune.sh 98 | ``` 99 | 100 | ## Calling the Model 101 | 102 | After fine-tuning, you can use the following code to call the fine-tuned model: 103 | 104 | ```python 105 | from peft import AutoPeftModelForCausalLM 106 | 107 | model = AutoPeftModelForCausalLM.from_pretrained( 108 | path_to_adapter, # Path to the adapter you trained 109 | device_map="auto", 110 | trust_remote_code=True 111 | ).eval() 112 | ``` 113 | -------------------------------------------------------------------------------- /finetune/README_zh.md: -------------------------------------------------------------------------------- 1 | [切换到中文版本](README_zh.md) 2 | 3 | [Switch to English Version](README.md) 4 | # Noname AI 模型微调 5 | 6 | ## 简介 7 | 8 | 本仓库包含了在自定义数据集上对 Noname AI 模型进行微调的脚本。在开始微调过程之前,请确保已安装所需的依赖项并获取了必要的模型和数据集文件。 9 | 10 | ## 依赖项 11 | 12 | 运行以下命令安装所需的依赖项: 13 | 14 | ```bash 15 | pip install peft deepspeed 16 | ``` 17 | 18 | ## 设置 19 | 20 | 1. 克隆此仓库: 21 | 22 | ```bash 23 | git clone https://github.com/204313508/noname_llm.git 24 | cd noname_llm/finetune 25 | ``` 26 | 27 | 2. 从 Hugging Face 克隆 v2.3 版本的模型文件: 28 | 29 | ```bash 30 | git lfs install 31 | git clone https://huggingface.co/huskyhong/noname-ai-v2_3-light 32 | ``` 33 | 34 | 3. 设置环境变量并根据您的需求调整训练脚本 (`finetune.sh`) 中的参数: 35 | 36 | ```bash 37 | export CUDA_DEVICE_MAX_CONNECTIONS=1 38 | export CUDA_VISIBLE_DEVICES=0 39 | 40 | MODEL="/tmp/pretrainmodel/nonameai" 41 | DATA="/tmp/code/data.json" 42 | ``` 43 | 44 | ## 数据集格式 45 | 46 | 数据集以 JSON 格式存储,示例如下: 47 | 48 | ```json 49 | [ 50 | { 51 | "id": "identity_0", 52 | "conversations": [ 53 | { 54 | "from": "user", 55 | "value": "请帮我编写一个技能,技能效果如下:你的技能效果描述" 56 | }, 57 | { 58 | "from": "assistant", 59 | "value": "你的技能代码" 60 | } 61 | ] 62 | }, 63 | { 64 | "id": "identity_1", 65 | "conversations": [ 66 | { 67 | "from": "user", 68 | "value": "请帮我编写一个技能,技能效果如下:你的技能效果描述" 69 | }, 70 | { 71 | "from": "assistant", 72 | "value": "你的技能代码" 73 | } 74 | ] 75 | }, 76 | ... 77 | ] 78 | ``` 79 | 80 | 81 | 82 | ## 参数修改说明 83 | 84 | 在 `finetune.py` 脚本中,您可以根据您的任务需求调整以下参数: 85 | 86 | - `--model_name_or_path`:指定模型的路径或名称。 87 | - `--data_path`:指定数据集的路径。 88 | - `--num_train_epochs`:指定训练的轮数。 89 | - `--per_device_train_batch_size`:指定每个设备的训练批次大小。 90 | - `--per_device_eval_batch_size`:指定每个设备的评估批次大小。 91 | - `--max_steps`:指定训练的最大步数。 92 | - `--learning_rate`:指定学习率。 93 | - `--weight_decay`:指定权重衰减。 94 | 95 | 96 | ## 训练 97 | 98 | 运行以下命令开始微调过程: 99 | 100 | ```bash 101 | bash finetune.sh 102 | ``` 103 | 104 | ## 调用模型 105 | 106 | 在微调完成后,您可以使用以下代码调用微调后的模型: 107 | 108 | ```python 109 | from peft import AutoPeftModelForCausalLM 110 | 111 | model = AutoPeftModelForCausalLM.from_pretrained( 112 | path_to_adapter, # 你训练得到的adapter路径 113 | device_map="auto", 114 | trust_remote_code=True 115 | ).eval() 116 | ``` 117 | -------------------------------------------------------------------------------- /finetune/finetune.py: -------------------------------------------------------------------------------- 1 | # This code is based on the revised code from fastchat based on tatsu-lab/stanford_alpaca. 2 | 3 | 4 | from dataclasses import dataclass, field 5 | import json 6 | import math 7 | import logging 8 | import os 9 | from typing import Dict, Optional, List 10 | import torch 11 | from torch.utils.data import Dataset 12 | from deepspeed import zero 13 | from deepspeed.runtime.zero.partition_parameters import ZeroParamStatus 14 | import transformers 15 | from transformers import Trainer, GPTQConfig, deepspeed 16 | from transformers.trainer_pt_utils import LabelSmoother 17 | from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training 18 | from accelerate.utils import DistributedType 19 | 20 | 21 | IGNORE_TOKEN_ID = LabelSmoother.ignore_index 22 | 23 | 24 | @dataclass 25 | class ModelArguments: 26 | model_name_or_path: Optional[str] = field(default="/tmp/pretrainmodel/nonameai") 27 | 28 | 29 | @dataclass 30 | class DataArguments: 31 | data_path: str = field( 32 | default=None, metadata={"help": "Path to the training data."} 33 | ) 34 | eval_data_path: str = field( 35 | default=None, metadata={"help": "Path to the evaluation data."} 36 | ) 37 | lazy_preprocess: bool = False 38 | 39 | 40 | @dataclass 41 | class TrainingArguments(transformers.TrainingArguments): 42 | cache_dir: Optional[str] = field(default=None) 43 | optim: str = field(default="adamw_torch") 44 | model_max_length: int = field( 45 | default=8192, 46 | metadata={ 47 | "help": "Maximum sequence length. Sequences will be right padded (and possibly truncated)." 48 | }, 49 | ) 50 | use_lora: bool = False 51 | 52 | 53 | @dataclass 54 | class LoraArguments: 55 | lora_r: int = 64 56 | lora_alpha: int = 16 57 | lora_dropout: float = 0.05 58 | lora_target_modules: List[str] = field( 59 | default_factory=lambda: ["c_attn", "c_proj", "w1", "w2"] 60 | ) 61 | lora_weight_path: str = "" 62 | lora_bias: str = "none" 63 | q_lora: bool = False 64 | 65 | 66 | def maybe_zero_3(param): 67 | if hasattr(param, "ds_id"): 68 | assert param.ds_status == ZeroParamStatus.NOT_AVAILABLE 69 | with zero.GatheredParameters([param]): 70 | param = param.data.detach().cpu().clone() 71 | else: 72 | param = param.detach().cpu().clone() 73 | return param 74 | 75 | 76 | # Borrowed from peft.utils.get_peft_model_state_dict 77 | def get_peft_state_maybe_zero_3(named_params, bias): 78 | if bias == "none": 79 | to_return = {k: t for k, t in named_params if "lora_" in k} 80 | elif bias == "all": 81 | to_return = {k: t for k, t in named_params if "lora_" in k or "bias" in k} 82 | elif bias == "lora_only": 83 | to_return = {} 84 | maybe_lora_bias = {} 85 | lora_bias_names = set() 86 | for k, t in named_params: 87 | if "lora_" in k: 88 | to_return[k] = t 89 | bias_name = k.split("lora_")[0] + "bias" 90 | lora_bias_names.add(bias_name) 91 | elif "bias" in k: 92 | maybe_lora_bias[k] = t 93 | for k, t in maybe_lora_bias: 94 | if bias_name in lora_bias_names: 95 | to_return[bias_name] = t 96 | else: 97 | raise NotImplementedError 98 | to_return = {k: maybe_zero_3(v) for k, v in to_return.items()} 99 | return to_return 100 | 101 | 102 | local_rank = None 103 | 104 | def rank0_print(*args): 105 | if local_rank == 0: 106 | print(*args) 107 | 108 | 109 | def safe_save_model_for_hf_trainer(trainer: transformers.Trainer, output_dir: str, bias="none"): 110 | """Collects the state dict and dump to disk.""" 111 | # check if zero3 mode enabled 112 | if deepspeed.is_deepspeed_zero3_enabled(): 113 | state_dict = trainer.model_wrapped._zero3_consolidated_16bit_state_dict() 114 | else: 115 | if trainer.args.use_lora: 116 | state_dict = get_peft_state_maybe_zero_3( 117 | trainer.model.named_parameters(), bias 118 | ) 119 | else: 120 | state_dict = trainer.model.state_dict() 121 | if trainer.args.should_save and trainer.args.local_rank == 0: 122 | trainer._save(output_dir, state_dict=state_dict) 123 | 124 | 125 | def preprocess( 126 | sources, 127 | tokenizer: transformers.PreTrainedTokenizer, 128 | max_len: int, 129 | system_message: str = "You are a helpful assistant." 130 | ) -> Dict: 131 | roles = {"user": "<|im_start|>user", "assistant": "<|im_start|>assistant"} 132 | 133 | im_start = tokenizer.im_start_id 134 | im_end = tokenizer.im_end_id 135 | nl_tokens = tokenizer('\n').input_ids 136 | _system = tokenizer('system').input_ids + nl_tokens 137 | _user = tokenizer('user').input_ids + nl_tokens 138 | _assistant = tokenizer('assistant').input_ids + nl_tokens 139 | 140 | # Apply prompt templates 141 | input_ids, targets = [], [] 142 | for i, source in enumerate(sources): 143 | if roles[source[0]["from"]] != roles["user"]: 144 | source = source[1:] 145 | 146 | input_id, target = [], [] 147 | system = [im_start] + _system + tokenizer(system_message).input_ids + [im_end] + nl_tokens 148 | input_id += system 149 | target += [im_start] + [IGNORE_TOKEN_ID] * (len(system)-3) + [im_end] + nl_tokens 150 | assert len(input_id) == len(target) 151 | for j, sentence in enumerate(source): 152 | role = roles[sentence["from"]] 153 | _input_id = tokenizer(role).input_ids + nl_tokens + \ 154 | tokenizer(sentence["value"]).input_ids + [im_end] + nl_tokens 155 | input_id += _input_id 156 | if role == '<|im_start|>user': 157 | _target = [im_start] + [IGNORE_TOKEN_ID] * (len(_input_id)-3) + [im_end] + nl_tokens 158 | elif role == '<|im_start|>assistant': 159 | _target = [im_start] + [IGNORE_TOKEN_ID] * len(tokenizer(role).input_ids) + \ 160 | _input_id[len(tokenizer(role).input_ids)+1:-2] + [im_end] + nl_tokens 161 | else: 162 | raise NotImplementedError 163 | target += _target 164 | assert len(input_id) == len(target) 165 | input_id += [tokenizer.pad_token_id] * (max_len - len(input_id)) 166 | target += [IGNORE_TOKEN_ID] * (max_len - len(target)) 167 | input_ids.append(input_id[:max_len]) 168 | targets.append(target[:max_len]) 169 | input_ids = torch.tensor(input_ids, dtype=torch.int) 170 | targets = torch.tensor(targets, dtype=torch.int) 171 | 172 | return dict( 173 | input_ids=input_ids, 174 | labels=targets, 175 | attention_mask=input_ids.ne(tokenizer.pad_token_id), 176 | ) 177 | 178 | 179 | class SupervisedDataset(Dataset): 180 | """Dataset for supervised fine-tuning.""" 181 | 182 | def __init__(self, raw_data, tokenizer: transformers.PreTrainedTokenizer, max_len: int): 183 | super(SupervisedDataset, self).__init__() 184 | 185 | rank0_print("Formatting inputs...") 186 | sources = [example["conversations"] for example in raw_data] 187 | data_dict = preprocess(sources, tokenizer, max_len) 188 | 189 | self.input_ids = data_dict["input_ids"] 190 | self.labels = data_dict["labels"] 191 | self.attention_mask = data_dict["attention_mask"] 192 | 193 | def __len__(self): 194 | return len(self.input_ids) 195 | 196 | def __getitem__(self, i) -> Dict[str, torch.Tensor]: 197 | return dict( 198 | input_ids=self.input_ids[i], 199 | labels=self.labels[i], 200 | attention_mask=self.attention_mask[i], 201 | ) 202 | 203 | 204 | class LazySupervisedDataset(Dataset): 205 | """Dataset for supervised fine-tuning.""" 206 | 207 | def __init__(self, raw_data, tokenizer: transformers.PreTrainedTokenizer, max_len: int): 208 | super(LazySupervisedDataset, self).__init__() 209 | self.tokenizer = tokenizer 210 | self.max_len = max_len 211 | 212 | rank0_print("Formatting inputs...Skip in lazy mode") 213 | self.tokenizer = tokenizer 214 | self.raw_data = raw_data 215 | self.cached_data_dict = {} 216 | 217 | def __len__(self): 218 | return len(self.raw_data) 219 | 220 | def __getitem__(self, i) -> Dict[str, torch.Tensor]: 221 | if i in self.cached_data_dict: 222 | return self.cached_data_dict[i] 223 | 224 | ret = preprocess([self.raw_data[i]["conversations"]], self.tokenizer, self.max_len) 225 | ret = dict( 226 | input_ids=ret["input_ids"][0], 227 | labels=ret["labels"][0], 228 | attention_mask=ret["attention_mask"][0], 229 | ) 230 | self.cached_data_dict[i] = ret 231 | 232 | return ret 233 | 234 | 235 | def make_supervised_data_module( 236 | tokenizer: transformers.PreTrainedTokenizer, data_args, max_len, 237 | ) -> Dict: 238 | """Make dataset and collator for supervised fine-tuning.""" 239 | dataset_cls = ( 240 | LazySupervisedDataset if data_args.lazy_preprocess else SupervisedDataset 241 | ) 242 | rank0_print("Loading data...") 243 | 244 | train_json = json.load(open(data_args.data_path, "r")) 245 | train_dataset = dataset_cls(train_json, tokenizer=tokenizer, max_len=max_len) 246 | 247 | if data_args.eval_data_path: 248 | eval_json = json.load(open(data_args.eval_data_path, "r")) 249 | eval_dataset = dataset_cls(eval_json, tokenizer=tokenizer, max_len=max_len) 250 | else: 251 | eval_dataset = None 252 | 253 | return dict(train_dataset=train_dataset, eval_dataset=eval_dataset) 254 | 255 | 256 | def train(): 257 | global local_rank 258 | 259 | parser = transformers.HfArgumentParser( 260 | (ModelArguments, DataArguments, TrainingArguments, LoraArguments) 261 | ) 262 | ( 263 | model_args, 264 | data_args, 265 | training_args, 266 | lora_args, 267 | ) = parser.parse_args_into_dataclasses() 268 | 269 | # This serves for single-gpu qlora. 270 | if getattr(training_args, 'deepspeed', None) and int(os.environ.get("WORLD_SIZE", 1))==1: 271 | training_args.distributed_state.distributed_type = DistributedType.DEEPSPEED 272 | 273 | compute_dtype = ( 274 | torch.float16 275 | if training_args.fp16 276 | else (torch.bfloat16 if training_args.bf16 else torch.float32) 277 | ) 278 | 279 | local_rank = training_args.local_rank 280 | 281 | device_map = None 282 | world_size = int(os.environ.get("WORLD_SIZE", 1)) 283 | ddp = world_size != 1 284 | if lora_args.q_lora: 285 | device_map = {"": int(os.environ.get("LOCAL_RANK") or 0)} if ddp else None 286 | if len(training_args.fsdp) > 0 or deepspeed.is_deepspeed_zero3_enabled(): 287 | logging.warning( 288 | "FSDP or ZeRO3 are not incompatible with QLoRA." 289 | ) 290 | 291 | # Set RoPE scaling factor 292 | config = transformers.AutoConfig.from_pretrained( 293 | model_args.model_name_or_path, 294 | cache_dir=training_args.cache_dir, 295 | trust_remote_code=True, 296 | ) 297 | config.use_cache = False 298 | 299 | # Load model and tokenizer 300 | model = transformers.AutoModelForCausalLM.from_pretrained( 301 | model_args.model_name_or_path, 302 | config=config, 303 | cache_dir=training_args.cache_dir, 304 | device_map=device_map, 305 | trust_remote_code=True, 306 | quantization_config=GPTQConfig( 307 | bits=4, disable_exllama=True 308 | ) 309 | if training_args.use_lora and lora_args.q_lora 310 | else None, 311 | ) 312 | tokenizer = transformers.AutoTokenizer.from_pretrained( 313 | model_args.model_name_or_path, 314 | cache_dir=training_args.cache_dir, 315 | model_max_length=training_args.model_max_length, 316 | padding_side="right", 317 | use_fast=False, 318 | trust_remote_code=True, 319 | ) 320 | tokenizer.pad_token_id = tokenizer.eod_id 321 | 322 | if training_args.use_lora: 323 | if lora_args.q_lora or 'chat' in model_args.model_name_or_path.lower(): 324 | modules_to_save = None 325 | else: 326 | modules_to_save = ["wte", "lm_head"] 327 | lora_config = LoraConfig( 328 | r=lora_args.lora_r, 329 | lora_alpha=lora_args.lora_alpha, 330 | target_modules=lora_args.lora_target_modules, 331 | lora_dropout=lora_args.lora_dropout, 332 | bias=lora_args.lora_bias, 333 | task_type="CAUSAL_LM", 334 | modules_to_save=modules_to_save # This argument serves for adding new tokens. 335 | ) 336 | if lora_args.q_lora: 337 | model = prepare_model_for_kbit_training( 338 | model, use_gradient_checkpointing=training_args.gradient_checkpointing 339 | ) 340 | 341 | model = get_peft_model(model, lora_config) 342 | 343 | if training_args.gradient_checkpointing: 344 | model.enable_input_require_grads() 345 | 346 | # Load data 347 | data_module = make_supervised_data_module( 348 | tokenizer=tokenizer, data_args=data_args, max_len=training_args.model_max_length 349 | ) 350 | 351 | # Start trainner 352 | trainer = Trainer( 353 | model=model, tokenizer=tokenizer, args=training_args, **data_module 354 | ) 355 | 356 | trainer.train() 357 | trainer.save_state() 358 | 359 | safe_save_model_for_hf_trainer(trainer=trainer, output_dir=training_args.output_dir, bias=lora_args.lora_bias) 360 | 361 | 362 | if __name__ == "__main__": 363 | train() 364 | -------------------------------------------------------------------------------- /finetune/finetune.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export CUDA_DEVICE_MAX_CONNECTIONS=1 3 | DIR=`pwd` 4 | 5 | 6 | MODEL="/tmp/pretrainmodel/nonameai" 7 | DATA="/tmp/code/data.json" 8 | 9 | export CUDA_VISIBLE_DEVICES=0 10 | 11 | python finetune.py \ 12 | --model_name_or_path $MODEL \ 13 | --data_path $DATA \ 14 | --bf16 True \ 15 | --output_dir /tmp/pretrainmodel/nonameai \ 16 | --num_train_epochs 5 \ 17 | --per_device_train_batch_size 2 \ 18 | --per_device_eval_batch_size 1 \ 19 | --gradient_accumulation_steps 8 \ 20 | --evaluation_strategy "no" \ 21 | --save_strategy "steps" \ 22 | --max_steps 2000 \ 23 | --save_steps 500 \ 24 | --save_total_limit 10 \ 25 | --learning_rate 3e-4 \ 26 | --weight_decay 0.1 \ 27 | --adam_beta2 0.95 \ 28 | --warmup_ratio 0.01 \ 29 | --lr_scheduler_type "cosine" \ 30 | --logging_steps 10 \ 31 | --report_to "none" \ 32 | --model_max_length 2048 \ 33 | --lazy_preprocess True \ 34 | --gradient_checkpointing \ 35 | --use_lora 36 | 37 | -------------------------------------------------------------------------------- /models/readme.md: -------------------------------------------------------------------------------- 1 | 将models放入该文件夹 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | accelerate==1.3.0 2 | altgraph==0.17.4 3 | certifi==2024.12.14 4 | charset-normalizer==3.4.1 5 | colorama==0.4.6 6 | einops==0.8.0 7 | filelock==3.13.1 8 | fsspec==2024.2.0 9 | huggingface-hub==0.27.1 10 | idna==3.10 11 | Jinja2==3.1.3 12 | MarkupSafe==2.1.5 13 | mpmath==1.3.0 14 | networkx==3.2.1 15 | numpy==1.26.3 16 | packaging==24.2 17 | pefile==2023.2.7 18 | pillow==10.2.0 19 | psutil==6.1.1 20 | pyinstaller==6.11.1 21 | pyinstaller-hooks-contrib==2025.0 22 | pywin32-ctypes==0.2.3 23 | PyYAML==6.0.2 24 | regex==2024.11.6 25 | requests==2.32.3 26 | safetensors==0.5.2 27 | sympy==1.13.1 28 | tokenizers==0.21.0 29 | torch==2.5.1 30 | torchaudio==2.5.1 31 | torchvision==0.20.1 32 | tqdm==4.67.1 33 | transformers==4.48.1 34 | typing_extensions==4.9.0 35 | urllib3==2.3.0 36 | -------------------------------------------------------------------------------- /sponsor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/204313508/noname_llm/a98f60da7a45ee0b52bd2c97c2b34ba52d0c18d4/sponsor.jpg -------------------------------------------------------------------------------- /webdemo.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer 3 | import torch 4 | from threading import Thread 5 | import time 6 | 7 | # 设置页面配置 8 | st.set_page_config( 9 | page_title="无名杀AI v3.0 在线版- by AKA臭脸羊驼", 10 | page_icon="🐐", 11 | layout="wide", 12 | initial_sidebar_state="expanded" 13 | ) 14 | 15 | # 模型加载函数 16 | @st.cache_resource 17 | def load_model(): 18 | try: 19 | with st.spinner("🦙 正在加载模型,首次加载可能需要较长时间..."): 20 | model = AutoModelForCausalLM.from_pretrained( 21 | "huskyhong/noname-ai-v3.0", 22 | torch_dtype="auto", 23 | device_map="auto" 24 | ) 25 | tokenizer = AutoTokenizer.from_pretrained("./models") 26 | return model, tokenizer 27 | except Exception as e: 28 | st.error(f"❌ 模型加载失败:{str(e)}") 29 | st.stop() 30 | 31 | # 加载模型 32 | model, tokenizer = load_model() 33 | 34 | # 侧边栏 35 | with st.sidebar: 36 | st.title("💖 支持开发者") 37 | try: 38 | st.image("赞赏码.jpg", 39 | caption="您的支持是我更新的动力", 40 | use_container_width=True) 41 | except FileNotFoundError: 42 | st.warning("找不到赞赏码图片") 43 | 44 | # 主界面 45 | st.title("🎮 无名杀AI v3.0 -网页端") 46 | 47 | st.markdown("---") 48 | 49 | # 初始化会话状态 50 | if "generating" not in st.session_state: 51 | st.session_state.update({ 52 | "generating": False, 53 | "first_token_received": False 54 | }) 55 | 56 | # 模式选择 57 | mode = st.radio("请选择生成模式:", ["技能生成", "卡牌生成"], horizontal=True) 58 | prompt_map = { 59 | "技能生成": "请帮我用JavaScript编写一个无名杀游戏的技能,技能效果如下:", 60 | "卡牌生成": "请帮我用JavaScript编写一张无名杀游戏的卡牌,卡牌效果如下:" 61 | } 62 | 63 | # 输入区域 64 | effect_desc = st.text_area( 65 | "✍️ 效果描述:", 66 | height=100, 67 | placeholder="请输入想要实现的技能/卡牌效果描述..." 68 | ) 69 | 70 | # 生成按钮 71 | if st.button("🚀 开始生成", use_container_width=True): 72 | if not effect_desc.strip(): 73 | st.warning("⚠️ 请输入效果描述!") 74 | st.stop() 75 | 76 | # 重置状态 77 | st.session_state.update({ 78 | "generating": True, 79 | "first_token_received": False 80 | }) 81 | 82 | # 构建提示词 83 | prompt = prompt_map[mode] + effect_desc.strip() 84 | 85 | messages = [ 86 | {"role": "system", "content": "你是由B站up主AKA臭脸臭羊驼训练得到的无名杀AI,旨在帮助用户编写无名杀技能或卡牌代码"}, 87 | {"role": "user", "content": prompt} 88 | ] 89 | 90 | # 准备生成参数 91 | text = tokenizer.apply_chat_template( 92 | messages, 93 | tokenize=False, 94 | add_generation_prompt=True 95 | ) 96 | model_inputs = tokenizer([text], return_tensors="pt").to(model.device) 97 | streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True) 98 | 99 | # 状态初始化 100 | status_area = st.empty() 101 | code_output = st.empty() 102 | full_response = "" 103 | start_time = time.time() 104 | 105 | # 启动生成线程 106 | def generate(): 107 | try: 108 | model.generate(**model_inputs, streamer=streamer, max_new_tokens=8192) 109 | except Exception as e: 110 | st.error(f"❌ 生成错误:{str(e)}") 111 | finally: 112 | st.session_state.generating = False 113 | 114 | thread = Thread(target=generate) 115 | thread.start() 116 | 117 | # 实时状态处理 118 | while st.session_state.generating: 119 | # 显示初始等待提示 120 | if not st.session_state.first_token_received: 121 | elapsed_time = time.time() - start_time 122 | status_message = f""" 123 | 🕒 正在努力生成中... ({elapsed_time:.1f}s) 124 | ![正在加载](https://i.gifer.com/ZZ5H.gif) 125 | ⏳ 模型初始化可能需要较长时间,请耐心等待 126 | """ 127 | status_area.markdown(status_message, unsafe_allow_html=True) 128 | 129 | # 尝试获取流式输出 130 | try: 131 | for token in streamer: 132 | # 收到第一个token时清除等待提示 133 | if not st.session_state.first_token_received: 134 | status_area.empty() 135 | st.session_state.first_token_received = True 136 | 137 | full_response += token 138 | code_output.code(full_response) 139 | break # 逐个token处理 140 | except StopIteration: 141 | break 142 | 143 | time.sleep(1) 144 | 145 | # 最终处理 146 | status_area.empty() 147 | if full_response: 148 | st.success("✅ 生成完成!") 149 | st.download_button( 150 | label="📥 下载代码", 151 | data=full_response, 152 | file_name="generated_code.js", 153 | mime="text/javascript", 154 | use_container_width=True 155 | ) 156 | else: 157 | st.warning("⚠️ 未能生成有效内容,请尝试调整输入描述") -------------------------------------------------------------------------------- /webdemo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/204313508/noname_llm/a98f60da7a45ee0b52bd2c97c2b34ba52d0c18d4/webdemo1.png -------------------------------------------------------------------------------- /webdemo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/204313508/noname_llm/a98f60da7a45ee0b52bd2c97c2b34ba52d0c18d4/webdemo2.png --------------------------------------------------------------------------------