Initial commit

This commit is contained in:
Stanislas0 2024-07-05 09:33:53 +08:00
commit 9e364eec5d
82 changed files with 5437 additions and 0 deletions

201
LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2024 CodeGeeX Team @ Zhipu AI
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

70
MODEL_LICENSE Normal file
View File

@ -0,0 +1,70 @@
The CodeGeeX4 License
1. 定义
“许可方”是指分发其软件的 CodeGeeX 团队。
“软件”是指根据本许可提供的 CodeGeeX4 模型参数。
2. 许可授予
根据本许可的条款和条件,许可方特此授予您非排他性、全球性、不可转让、不可再许可、可撤销、免版税的版权许可。
本许可允许您免费使用本仓库中的所有开源模型进行学术研究,对于希望将模型用于商业目的的用户,需在[这里](https://open.bigmodel.cn/mla/form)完成登记。经过登记的用户可以免费使用本模型进行商业活动,但必须遵守本许可的所有条款和条件。
上述版权声明和本许可声明应包含在本软件的所有副本或重要部分中。
如果您分发或提供 THUDM / 智谱AI 关于 CodeGeeX4 开源模型的材料(或其任何衍生作品),或使用其中任何材料(包括 CodeGeeX4 系列的所有开源模型)的产品或服务,您应:
(A) 随任何此类 THUDM / 智谱AI 材料提供本协议的副本;
(B) 在相关网站、用户界面、博客文章、关于页面或产品文档上突出显示 “Built with CodeGeeX4”。
如果您使用 THUDM / 智谱AI的 CodeGeeX4 开源模型的材料来创建、训练、微调或以其他方式改进已分发或可用的 AI 模型,您还应在任何此类 AI 模型名称的开头添加 “CodeGeeX4”。
3. 限制
您不得出于任何军事或非法目的使用、复制、修改、合并、发布、分发、复制或创建本软件的全部或部分衍生作品。
您不得利用本软件从事任何危害国家安全和国家统一,危害社会公共利益及公序良俗,侵犯他人商业秘密、知识产权、名誉权、肖像权、财产权等权益的行为。
您在使用中应遵循使用地所适用的法律法规政策、道德规范等要求。
4. 免责声明
本软件“按原样”提供,不提供任何明示或暗示的保证,包括但不限于对适销性、特定用途的适用性和非侵权性的保证。
在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权行为还是其他方面,由软件或软件的使用或其他交易引起、由软件引起或与之相关
软件。
5. 责任限制
除适用法律禁止的范围外,在任何情况下且根据任何法律理论,无论是基于侵权行为、疏忽、合同、责任或其他原因,任何许可方均不对您承担任何直接、间接、特殊、偶然、示范性、
或间接损害,或任何其他商业损失,即使许可人已被告知此类损害的可能性。
6. 争议解决
本许可受中华人民共和国法律管辖并按其解释。 因本许可引起的或与本许可有关的任何争议应提交北京市海淀区人民法院。
请注意,许可证可能会更新到更全面的版本。 有关许可和版权的任何问题,请通过 license@zhipuai.cn 与我们联系。
1. Definitions
“Licensor” means the CodeGeeX Team that distributes its Software.
“Software” means the CodeGeeX4 model parameters made available under this license.
2. License
Under the terms and conditions of this license, the Licensor hereby grants you a non-exclusive, worldwide, non-transferable, non-sublicensable, revocable, royalty-free copyright license.
This license allows you to use all open source models in this repository for free for academic research. For users who wish to use the models for commercial purposes, please do so [here](https://open.bigmodel.cn/mla/form)
Complete registration. Registered users are free to use this model for commercial activities, but must comply with all terms and conditions of this license.
The copyright notice and this license notice shall be included in all copies or substantial portions of the Software.
If you distribute or provide THUDM / Zhipu AI materials on the CodeGeeX4 open source model (or any derivative works thereof), or products or services that use any materials therein (including all open source models of the CodeGeeX4 series), you should:
(A) Provide a copy of this Agreement with any such THUDM/Zhipu AI Materials;
(B) Prominently display "Built with CodeGeeX4" on the relevant website, user interface, blog post, related page or product documentation.
If you use materials from THUDM/Zhipu AI's CodeGeeX4 model to create, train, operate, or otherwise improve assigned or available AI models, you should also add "CodeGeeX4" to the beginning of any such AI model name.
3. Restrictions
You are not allowed to use, copy, modify, merge, publish, distribute, copy or create all or part of the derivative works of this software for any military or illegal purposes.
You are not allowed to use this software to engage in any behavior that endangers national security and unity, endangers social public interests and public order, infringes on the rights and interests of others such as trade secrets, intellectual property rights, reputation rights, portrait rights, and property rights.
You should comply with the applicable laws, regulations, policies, ethical standards, and other requirements in the place of use during use.
4. Disclaimer
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5. Limitation of Liability
EXCEPT TO THE EXTENT PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL THEORY, WHETHER BASED IN TORT,
NEGLIGENCE, CONTRACT, LIABILITY, OR OTHERWISE WILL ANY LICENSOR BE LIABLE TO YOU FOR ANY DIRECT, INDIRECT, SPECIAL,
INCIDENTAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES, OR ANY OTHER COMMERCIAL LOSSES, EVEN IF THE LICENSOR HAS BEEN ADVISED
OF THE POSSIBILITY OF SUCH DAMAGES.
6. Dispute Resolution
This license shall be governed and construed in accordance with the laws of Peoples Republic of China. Any dispute
arising from or in connection with this License shall be submitted to Haidian District People's Court in Beijing.
Note that the license is subject to update to a more comprehensive version. For any questions related to the license and
copyright, please contact us at license@zhipuai.cn.

86
README.md Normal file
View File

@ -0,0 +1,86 @@
![](resources/logo.jpeg)
<p align="center">
🏠 <a href="https://codegeex.cn" target="_blank">Homepage</a>|🛠 Extensions <a href="https://marketplace.visualstudio.com/items?itemName=aminer.codegeex" target="_blank">VS Code</a>, <a href="https://plugins.jetbrains.com/plugin/20587-codegeex" target="_blank">Jetbrains</a>|🤗 <a href="https://huggingface.co/THUDM/codegeex4-all-9b" target="_blank">HF Repo</a> | 🪧 <a href="https://huggingface.co/spaces/THUDM/CodeGeeX" target="_blank">HF DEMO</a>
</p>
[English](./README.md) | [中文](./README_zh.md)
# CodeGeeX4: Open Multilingual Code Generation Model
We introduce CodeGeeX4-ALL-9B, the open-source version of the latest CodeGeeX4 model series. It is a multilingual code generation model continually trained on the [GLM-4-9B](https://github.com/THUDM/GLM-4), significantly enhancing its code generation capabilities. Using a single CodeGeeX4-ALL-9B model, it can support comprehensive functions such as code completion and generation, code interpreter, web search, function call, repository-level code Q&A, covering various scenarios of software development. CodeGeeX4-ALL-9B has achieved highly competitive performance on public benchmarks, such as [BigCodeBench](https://huggingface.co/datasets/bigcode/bigcodebench) and [NaturalCodeBench](https://github.com/THUDM/NaturalCodeBench). It is currently the most powerful code generation model with less than 10B parameters, even surpassing much larger general-purpose models, achieving the best balance in terms of inference speed and model performance.
## Model List
| Model | Type | Seq Length | Download |
|-------------------|------|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| codegeex4-all-9b | Chat | 128K | [🤗 Huggingface](https://huggingface.co/THUDM/codegeex4-all-9b) [🤖 ModelScope](https://modelscope.cn/models/ZhipuAI/codegeex4-all-9b) [🟣 WiseModel](https://wisemodel.cn/models/ZhipuAI/codegeex4-all-9b) |
## Get Started
Use `4.39.0<=transformers<=4.40.2` to quickly launch [codegeex4-all-9b](https://huggingface.co/THUDM/codegeex4-all-9b)
```python
from transformers import AutoTokenizer, AutoModelForCausalLM
device = "cuda" if torch.cuda.is_available() else "cpu"
tokenizer = AutoTokenizer.from_pretrained("THUDM/codegeex4-all-9b", trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
"THUDM/codegeex4-all-9b",
torch_dtype=torch.bfloat16,
low_cpu_mem_usage=True,
trust_remote_code=True
).to(device).eval()
inputs = tokenizer.apply_chat_template([{"role": "user", "content": "write a quick sort"}], add_generation_prompt=True, tokenize=True, return_tensors="pt", return_dict=True ).to(device)
with torch.no_grad():
outputs = model.generate(**inputs)
outputs = outputs[:, inputs['input_ids'].shape[1]:]
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
```
## Tutorials
CodeGeeX4-ALL-9B provides three user guides to help users quickly understand and use the model:
1. **[System Prompt Guideline](./guides/System_prompt_guideline.md)**: This guide introduces how to use system prompts in CodeGeeX4-ALL-9B, including the VSCode extension official system prompt, customized system prompts, and some tips for maintaining multi-turn dialogue history.
2. **[Infilling Guideline](./guides/Infilling_guideline.md)**: This guide explains the VSCode extension official infilling format, covering general infilling, cross-file infilling, and generating a new file in a repository.
3. **[repository Tasks Guideline](./guides/Repository_tasks_guideline.md)**: This guide demonstrates how to use repository tasks in CodeGeeX4-ALL-9B, including QA tasks at the repository level and how to trigger the aicommiter capability of CodeGeeX4-ALL-9B to perform deletions, additions, and changes to files at the repository level.
These guides aim to provide a comprehensive understanding and facilitate efficient use of the model.
## Evaluation
CodeGeeX4-ALL-9B is ranked as the most powerful model under 10 billion parameters, even surpassing general models several times its size, achieving the best balance between inference performance and model effectiveness.
CodeGeeX4-ALL-9B scored `48.9` and `40.4` for the `complete` and `instruct` tasks of BigCodeBench, which are the highest scores among models with less than 20 billion parameters.
![BigCodeBench Test Results](./metric/pics/Bigcodebench.png)
In CRUXEval, a benchmark for testing code reasoning, understanding, and execution capabilities, CodeGeeX4-ALL-9B presented remarkable results with its COT (chain-of-thought) abilities. From easy code generation tasks in HumanEval and MBPP, to very challenging tasks in NaturalCodeBench, CodeGeeX4-ALL-9B also achieved outstanding performance at its scale. It is currently the only code model that supports Function Call capabilities and even achieves a better execution success rate than GPT-4.
![Function Call Evaluation](./metric/pics/FunctionCall.png)
Furthermore, in the "Code Needle In A Haystack" (NIAH) evaluation, the CodeGeeX4-ALL-9B model demonstrated its ability to retrieve code within contexts up to 128K, achieving a 100% retrieval accuracy in all python scripts.
<p align="center">
<img src=./metric/pics/NIAH_PYTHON.png alt="图片1描述" width="45%">
<img src="./metric/pics/NIAH_ALL.png" alt="图片2描述" width="45%">
</p>
Details of the evaluation results can be found in the **[Evaluation](./metric/README.md)**.
## License
The code in this repository is open source under the [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) license. The model weights are licensed under the [Model License](MODEL_LICENSE). CodeGeeX4-9B weights are open for academic research. For users who wish to use the models for commercial purposes, please fill in the [registration form](https://open.bigmodel.cn/mla/form).
## Citation
If you find our work helpful, please feel free to cite the following paper:
```
@inproceedings{zheng2023codegeex,
title={CodeGeeX: A Pre-Trained Model for Code Generation with Multilingual Evaluations on HumanEval-X},
author={Qinkai Zheng and Xiao Xia and Xu Zou and Yuxiao Dong and Shan Wang and Yufei Xue and Zihan Wang and Lei Shen and Andi Wang and Yang Li and Teng Su and Zhilin Yang and Jie Tang},
booktitle={KDD},
year={2023}
}
```

87
README_zh.md Normal file
View File

@ -0,0 +1,87 @@
![](resources/logo.jpeg)
<p align="center">
🏠 <a href="https://codegeex.cn" target="_blank">Homepage</a>|🛠 Extensions <a href="https://marketplace.visualstudio.com/items?itemName=aminer.codegeex" target="_blank">VS Code</a>, <a href="https://plugins.jetbrains.com/plugin/20587-codegeex" target="_blank">Jetbrains</a>|🤗 <a href="https://huggingface.co/THUDM/codegeex4-all-9b" target="_blank">HF Repo</a> | 🪧 <a href="https://huggingface.co/spaces/THUDM/CodeGeeX" target="_blank">HF DEMO</a>
</p>
[English](./README.md) | [中文](./README_zh.md)
# CodeGeeX4: 开源多语言代码生成模型
我们推出了 CodeGeeX4-ALL-9B这是最新的 CodeGeeX4 系列模型的开源版本。该模型是在 [GLM-4-9B](https://github.com/THUDM/GLM-4) 基础上持续训练的多语言代码生成模型,显著提升了代码生成能力。使用单个 CodeGeeX4-ALL-9B 模型可以支持代码补全与生成、代码解释、联网搜索、函数调用、仓库级代码问答等多种功能覆盖了软件开发的各个场景。CodeGeeX4-ALL-9B 在 [BigCodeBench](https://huggingface.co/datasets/bigcode/bigcodebench) 和 [NaturalCodeBench](https://github.com/THUDM/NaturalCodeBench) 等公开基准测试中取得了极具竞争力的表现。它是目前参数量少于 100 亿的最强代码生成模型,甚至超越了更大的通用模型,在推理速度和模型性能方面达到了最佳平衡。
## 模型列表
| 模型 | 类型 | 上下文长度 | 下载地址 |
|-------------------|------|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| codegeex4-all-9b | Chat | 128K | [🤗 Huggingface](https://huggingface.co/THUDM/codegeex4-all-9b) [🤖 ModelScope](https://modelscope.cn/models/ZhipuAI/codegeex4-all-9b) [🟣 WiseModel](https://wisemodel.cn/models/ZhipuAI/codegeex4-all-9b) |
## 快速开始
请使用 `4.39.0<=transformers<=4.40.2` 部署 [codegeex4-all-9b](https://huggingface.co/THUDM/codegeex4-all-9b)
```python
from transformers import AutoTokenizer, AutoModelForCausalLM
device = "cuda" if torch.cuda.is_available() else "cpu"
tokenizer = AutoTokenizer.from_pretrained("THUDM/codegeex4-all-9b", trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
"THUDM/codegeex4-all-9b",
torch_dtype=torch.bfloat16,
low_cpu_mem_usage=True,
trust_remote_code=True
).to(device).eval()
inputs = tokenizer.apply_chat_template([{"role": "user", "content": "write a quick sort"}], add_generation_prompt=True, tokenize=True, return_tensors="pt", return_dict=True).to(device)
with torch.no_grad():
outputs = model.generate(**inputs)
outputs = outputs[:, inputs['input_ids'].shape[1]:]
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
```
## 用户指南
我们为 CodeGeeX4-ALL-9B 提供了用户指南,帮助用户快速了解和使用该模型:
![ALL Fuctions](./resources/all_functions.jpg)
1. **[系统提示指南](./guides/System_prompt_guideline_zh.md)**:本指南介绍了如何在 CodeGeeX4-ALL-9B 中使用系统提示,包括 VSCode 插件的官方系统提示、自定义系统提示以及维护多轮对话历史的一些技巧。
2. **[上下文补全指南](./guides/Infilling_guideline_zh.md)**:本指南解释了 VSCode 插件的官方填充格式,涵盖一般补全、跨文件补全和在仓库中生成新文件。
3. **[项目级代码生成指南](./guides/Repository_tasks_guideline_zh.md)**:本指南展示了如何在 CodeGeeX4-ALL-9B 中使用项目级任务,包括项目级别的问答任务,以及如何触发 CodeGeeX4-ALL-9B 的 aicommiter 功能以执行仓库级别任务中的删除、添加和更改文件操作。
这些指南旨在帮助大家全面理解模型的用法并更好发挥模型的能力。
## 评测指标
CodeGeeX4-ALL-9B 被评为参数量100 亿内的最强模型,甚至超越了参数量大几倍的通用模型,在推理性能和模型能力之间达到了最佳效果。
在 BigCodeBench 的 complete 和 instruct 任务中CodeGeeX4-ALL-9B 分别取得了 `48.9``40.4` 的高分,这在参数量 200 亿内的模型中是最高的分数。
![BigCodeBench Test Results](./metric/pics/Bigcodebench.png)
Crux-Eval 是测试代码推理、理解和执行能力的基准测试,借助于其强大的 COT 能力CodeGeeX4-ALL-9B 展现出色的表现。在 HumanEval、MBPP 和 NaturalCodeBench 等代码生成任务中CodeGeeX4-ALL-9B 也取得了出色的成绩。目前,它是唯一支持 Function Call 功能的代码模型,甚至取得了比 GPT-4 更高的分数。
![Function Call Evaluation](./metric/pics/FunctionCall.png)
此外在“Code Needle In A Haystack” (NIAH) 评估中CodeGeeX4-ALL-9B 模型展示了在 128K 范围内检索代码的能力在python语言环境达到了 100% 的检索准确率,并在跨文件补全任务中表现出色。
<p align="center">
<img src=./metric/pics/NIAH_PYTHON.png alt="图片1描述" width="45%">
<img src="./metric/pics/NIAH_ALL.png" alt="图片2描述" width="45%">
</p>
更详细的评估结果请看 **[评估结果](./metric/README_zh.md)** 。
## 许可证
本仓库中的代码是根据 [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) 许可证开源的。模型权重根据 [模型许可证](MODEL_LICENSE) 许可。CodeGeeX4-9B 权重对学术研究开放。对于希望将模型用于商业目的的用户,请填写 [登记表](https://open.bigmodel.cn/mla/form)。
## 引用
如果您觉得我们的工作对您有帮助,欢迎引用以下论文:
```
@inproceedings{zheng2023codegeex,
title={CodeGeeX: A Pre-Trained Model for Code Generation with Multilingual Evaluations on HumanEval-X},
author={Qinkai Zheng and Xiao Xia and Xu Zou and Yuxiao Dong and Shan Wang and Yufei Xue and Zihan Wang and Lei Shen and Andi Wang and Yang Li and Teng Su and Zhilin Yang and Jie Tang},
booktitle={KDD},
year={2023}
}
```

View File

@ -0,0 +1,216 @@
**Code Completion Tutorial: Contextual, Cross-File, and Project-Level Completion**
This tutorial primarily introduces the code completion capabilities of plugin-enabled models. These capabilities include contextual completion, cross-file completion, and project-level file completion.
- **Contextual Completion:** Within the same code file, based on the cursor's position and the surrounding context.
- **Cross-File Completion:** Enhances code completion capabilities by incorporating dependencies or related files of the current code file.
- **Project-Level Completion:** The model can generate complete new files based on your project information and requirements.
You can use the CodeGeeX4-ALL-9B-128k model and control memory requirements by setting different `max_length` values. For example, you can set `max_length` to 16k or 32k to run the model on consumer-grade graphics cards.
<a name="heading_0"></a>**Code Completion Usage Tutorial**
<a name="heading_1"></a>1. **Contextual Completion**
1. **File Path:** `"###PATH:"` + relative file path or file name
2. **Language Tag:** This is very important and must be included. The list of languages is mentioned above, and the format generally starts with the language's initial capital letter, with a few exceptions. If unsure about the language, you can leave it blank after the colon. All language tags start with `"###LANGUAGE:"`.
3. **Two Modes:** `"###MODE:"`, `LINE` generates a single line, and `BLOCK` generates multiple lines. The default is `BLOCK` mode.
4. **Format:**
```
<|user|>
###PATH:{path}
###LANGUAGE:{code_language}
###MODE:{LINE/BLOCK}
<|code_suffix|>{code}<|code_prefix|>{code}<|code_middle|><|assistant|>\n
```
5. Example:
When all information including path, code_language, mode, suffix, and prefix is provided:
```
<|user|>
###PATH:src.py
###LANGUAGE:Python
###MODE:LINE/BLOCK
<|code_suffix|> else:
depth -= 1
return max_depth
return [parse_paren_group(x) for x in paren_string.split(' ') if x]
<|code_prefix|>from typing import List
def parse_nested_parens(paren_string: str) -> List[int]:
""" Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
For each of the group, output the deepest level of nesting of parentheses.
E.g. (()()) has maximum two levels of nesting while ((())) has three.
>>> parse_nested_parens('(()()) ((())) () ((())()())')
[2, 3, 1, 3]
"""
<|code_middle|><|assistant|>\n
```
- Situation with no language and no suffix provided
```
<|user|>
###PATH:src.py
###LANGUAGE:
###MODE:LINE/BLOCK
<|code_suffix|><|code_prefix|>from typing import List
def parse_nested_parens(paren_string: str) -> List[int]:
""" Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
For each of the group, output the deepest level of nesting of parentheses.
E.g. (()()) has maximum two levels of nesting while ((())) has three.
>>> parse_nested_parens('(()()) ((())) () ((())()())')
[2, 3, 1, 3]
"""
<|code_middle|><|assistant|>\n
```
<a name="heading_2"></a>2. **Cross File Infilling**
1. Please format reference code as below:
```
###REFERENCE:
###PATH: relative file path or file name
code snippet
###REFERENCE:
###PATH: relative file path or file name
code snippet
```
2. **File Path:** `"###PATH:"` + relative file path or file name
3. **Language Tag:** This is very important and must be included. The list of languages is mentioned above, and the format generally starts with the language's initial capital letter, with a few exceptions. If unsure about the language, you can leave it blank after the colon. All language tags start with `"###LANGUAGE:"`.
4. **Two Modes:** `"###MODE:"`, `LINE` generates a single line, and `BLOCK` generates multiple lines. The default is `BLOCK` mode.
5. **Format:**
```
<|user|>
###REFERENCE:
###PATH:{path}
{code}
...
...
...
###REFERENCE:
###PATH:{path}
{code}
###PATH:{path}\n\n###LANGUAGE:{code_language}\n###MODE:{LINE/BLOCK}\n<|code_suffix|>{code}<|code_prefix|>{code}<|code_middle|><|assistant|>\n
```
6. Example:
```
|Python
<|user|>
###PATH:./sort/quick_sort.py
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
###PATH:src.py
###LANGUAGE:Python
###MODE:LINE/BLOCK
<|code_suffix|> else:
depth -= 1
return max_depth
return [parse_paren_group(x) for x in paren_string.split(' ') if x]
<|code_prefix|>from typing import List
def parse_nested_parens(paren_string: str) -> List[int]:
""" Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
For each of the group, output the deepest level of nesting of parentheses.
E.g. (()()) has maximum two levels of nesting while ((())) has three.
>>> parse_nested_parens('(()()) ((())) () ((())()())')
[2, 3, 1, 3]
"""
<|code_middle|><|assistant|>\n
```
<a name="heading_3"></a>3. **Repository Level File Generation**
1. You can use the project-level add, delete, and modify format to complete the task of adding a file in the project.
2. Related files: Example format is as follows:
```
###REFERENCE:
###PATH: relative file path or file name
代码
###REFERENCE:
###PATH: relative file path or file name
代码
```
3. **File Path:** `"###PATH:"` + relative file path or file name
4. **Language Tag:** This is very important and must be included. The list of languages is mentioned above, and the format generally starts with the language's initial capital letter, with a few exceptions. If unsure about the language, you can leave it blank after the colon. All language tags start with `"###LANGUAGE:"`.
5. **Two Modes:** `"###MODE:"`, `LINE` generates a single line, and `BLOCK` generates multiple lines. The default is `BLOCK` mode.
6. **Format:**
```
<|user|>
###REFERENCE:
###PATH:{path}
{code}
...
...
...
###REFERENCE:
###PATH:{path}
{code}
###PATH:{path}
###LANGUAGE:{code_language}
###MODE:{LINE/BLOCK}
<|code_suffix|>{code}<|code_prefix|>{code}<|code_middle|><|assistant|>\n
```
7. Example:
```
<|user|>
###PATH:./sort/quick_sort.py
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
###PATH:src.py
###LANGUAGE:Python
###MODE:LINE/BLOCK
<|code_suffix|> else:
depth -= 1
return max_depth
return [parse_paren_group(x) for x in paren_string.split(' ') if x]
<|code_prefix|>from typing import List
def parse_nested_parens(paren_string: str) -> List[int]:
""" Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
For each of the group, output the deepest level of nesting of parentheses.
E.g. (()()) has maximum two levels of nesting while ((())) has three.
>>> parse_nested_parens('(()()) ((())) () ((())()())')
[2, 3, 1, 3]
"""
<|code_middle|><|assistant|>\n
```

View File

@ -0,0 +1,215 @@
**代码补全使用教程,上下文补全,跨文件补全,项目级别补全**
本篇教程中,主要介绍了插件功能的模型的代码补全能力。代码补全能力包括上下文补全,跨文件补全和项目级文件补全。
- 上下文补全:在同一个代码文件内,根据光标所在位置,上下文信息。
- 跨文件补全:引入当前代码文件的依赖文件或者相关文件,增强代码补全的能力。
- 项目级别补全:模型可以根据您的项目信息,以及您的需求,为您生成完整的新文件。
您可以使用CodeGeeX4-ALL-9B-128k模型通过设置不同的max_length控制对显存的需求。例如您可以将max_length设置在16k或者32k以便将模型跑在消费级显卡上
<a name="heading_0"></a>**代码补全使用教程**
<a name="heading_1"></a>1. **上下文填空**
1. 文件路径:"###PATH:" + 文件相对路径或文件名
2. 语言标签非常重要,必须要加上,语言列表见上方,格式一般是语言开头大写,有个别特殊;在不确定语言的情况下,冒号后面可以空着),所有语言标签都是以"###LANGUAGE:"开头,不作另外区分。
3. 两个种模式:"###MODE:"LINE生成单行BLOCK生成多行。默认BLOCK模式。
4. 格式:
```
<|user|>
###PATH:{path}
###LANGUAGE:{code_language}
###MODE:{LINE/BLOCK}
<|code_suffix|>{code}<|code_prefix|>{code}<|code_middle|><|assistant|>\n
```
5. 示例如下:
- 有path,code_language,mode,suffix,prefix全部信息的情况
```
<|user|>
###PATH:src.py
###LANGUAGE:Python
###MODE:LINE/BLOCK
<|code_suffix|> else:
depth -= 1
return max_depth
return [parse_paren_group(x) for x in paren_string.split(' ') if x]
<|code_prefix|>from typing import List
def parse_nested_parens(paren_string: str) -> List[int]:
""" Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
For each of the group, output the deepest level of nesting of parentheses.
E.g. (()()) has maximum two levels of nesting while ((())) has three.
>>> parse_nested_parens('(()()) ((())) () ((())()())')
[2, 3, 1, 3]
"""
<|code_middle|><|assistant|>\n
```
- 没有语言、没有后缀的情况
```
<|user|>
###PATH:src.py
###LANGUAGE:
###MODE:LINE/BLOCK
<|code_suffix|><|code_prefix|>from typing import List
def parse_nested_parens(paren_string: str) -> List[int]:
""" Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
For each of the group, output the deepest level of nesting of parentheses.
E.g. (()()) has maximum two levels of nesting while ((())) has three.
>>> parse_nested_parens('(()()) ((())) () ((())()())')
[2, 3, 1, 3]
"""
<|code_middle|><|assistant|>\n
```
<a name="heading_2"></a>2. **跨文件补全**
1. 相关文件:格式示例如下
```
###REFERENCE:
###PATH: 文件相对路径或文件名
代码
###REFERENCE:
###PATH: 文件相对路径或文件名
代码
```
2. 文件路径:"###PATH:" + 文件相对路径或文件名
3. 语言标签非常重要,必须要加上,语言列表见上方,格式一般是语言开头大写,有个别特殊;在不确定语言的情况下,冒号后面可以空着),所有语言标签都是以"###LANGUAGE:"开头,不作另外区分。
4. 两个种模式:"###MODE:"LINE生成单行BLOCK生成多行。默认BLOCK模式。
5. 格式:
```
<|user|>
###REFERENCE:
###PATH:{path}
{code}
...
...
...
###REFERENCE:
###PATH:{path}
{code}
###PATH:{path}\n\n###LANGUAGE:{code_language}\n###MODE:{LINE/BLOCK}\n<|code_suffix|>{code}<|code_prefix|>{code}<|code_middle|><|assistant|>
6. 示例如下:
|Python
<|user|>
###PATH:./sort/quick_sort.py
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
###PATH:src.py
###LANGUAGE:Python
###MODE:LINE/BLOCK
<|code_suffix|> else:
depth -= 1
return max_depth
return [parse_paren_group(x) for x in paren_string.split(' ') if x]
<|code_prefix|>from typing import List
def parse_nested_parens(paren_string: str) -> List[int]:
""" Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
For each of the group, output the deepest level of nesting of parentheses.
E.g. (()()) has maximum two levels of nesting while ((())) has three.
>>> parse_nested_parens('(()()) ((())) () ((())()())')
[2, 3, 1, 3]
"""
<|code_middle|><|assistant|>\n
```
<a name="heading_3"></a>3. **项目级文件补全**
1. 您可以使用项目级增删改的格式,完成在项目中补一个文件的任务
2. 相关文件:格式示例如下
```
###REFERENCE:
###PATH: 文件相对路径或文件名
代码
###REFERENCE:
###PATH: 文件相对路径或文件名
代码
```
3. 文件路径:"###PATH:" + 文件相对路径或文件名
4. 语言标签非常重要,必须要加上,语言列表见上方,格式一般是语言开头大写,有个别特殊;在不确定语言的情况下,冒号后面可以空着),所有语言标签都是以"###LANGUAGE:"开头,不作另外区分。
5. 两个种模式:"###MODE:"LINE生成单行BLOCK生成多行。默认BLOCK模式。
6. 格式:
```
<|user|>
###REFERENCE:
###PATH:{path}
{code}
...
...
...
###REFERENCE:
###PATH:{path}
{code}
###PATH:{path}
###LANGUAGE:{code_language}
###MODE:{LINE/BLOCK}
<|code_suffix|>{code}<|code_prefix|>{code}<|code_middle|><|assistant|>\n
```
7. 示例如下:
```
<|user|>
###PATH:./sort/quick_sort.py
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
###PATH:src.py
###LANGUAGE:Python
###MODE:LINE/BLOCK
<|code_suffix|> else:
depth -= 1
return max_depth
return [parse_paren_group(x) for x in paren_string.split(' ') if x]
<|code_prefix|>from typing import List
def parse_nested_parens(paren_string: str) -> List[int]:
""" Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
For each of the group, output the deepest level of nesting of parentheses.
E.g. (()()) has maximum two levels of nesting while ((())) has three.
>>> parse_nested_parens('(()()) ((())) () ((())()())')
[2, 3, 1, 3]
"""
<|code_middle|><|assistant|>\n
```

View File

@ -0,0 +1,189 @@
**Project-Level Usage Tutorial: Project File Add, Delete, Modify, Project Q&A**
For project-level tasks, it is recommended to use the CodeGeeX4-ALL-9B-128k model version. This model supports 128k context, which is approximately 10,000 lines of code.
Due to the inference time cost and the possibility of project content exceeding 128k, we strongly recommend trimming the model output when using the CodeGeeX4-ALL-9B-128k model.
**Model Output Trimming**
- BM25 & embedding recall
- Truncate input exceeding 128k (make sure to retain theme special tokens, such as [CLS], [SEP], etc.)
- Etc.
Below is a list of languages supported by CodeGeeX4. You can use the primary languages as an initial way to trim the output.
**Primary Languages (30 out of 310 languages supported)**
```
['c', 'c++', 'csharp', 'cuda', 'dart', 'go', 'haskell', 'html', 'java', 'javascript', 'json', 'kotlin', 'lua', 'markdown', 'objective-c++', 'pascal', 'php', 'python', 'r', 'ruby', 'rust', 'scala', 'shell', 'sql', 'swift', 'tex', 'txt', 'typescript', 'vue', 'xml']
```
<a name="heading_0"></a>**Repository-Level Task Tutorial**
After processing the model input (within 128k),
we need a special input format to activate the model's project Q&A and project file add, delete, and modify functions.
<a name="heading_1"></a>1. **Repository Q&A**
1. **System Prompt**
The system prompt here uses the same prompt as Q&A. We support both Chinese and English system prompts. The system prompt language does not directly affect the model's output language. You can use phrases like "请用中文回答。" or "Please answer in English." at the end of the system prompt to induce the model's output language.
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.(请用中文回答。/Please answer in English.)
```
2. Repository Q&A Format
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.<|user|>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
<<Query>><|assistant|>\n
```
3. Example
- Prompt
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.<|user|>
###PATH: sort.py
def quick_sort(arr):
if len(arr) <= 1:
return arr
needle = "codegeex4-all-9b"
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
###PATH: calculator.py
def calculate(a, b, op):
if op == '+':
return a + b
elif op == '-':
return a - b
elif op == '*':
return a \* b
elif op == '/':
if b == 0:
return 'devider can not be 0'
else:
return a / b
else:
return 'error'
what's the needle value in above code snipptss<|assistant|>\n
```
- output
```
Acoording to the above code snippet, the needle value is "codegeex4-all-9b".
```
<a name="heading_2"></a>2. **Repository File Add, Delete, Modify**
1. **System Prompt**
For the task of adding, deleting, and modifying project files, a separate system prompt is needed. Similarly, we support both Chinese and English system prompts here. Since the model's output is code, it is not recommended to include content that induces responses in Chinese or English in the system prompt.
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码。请根据用户给出的项目仓库中的代码以及用户提出的需求生成新的代码或者更改已有代码。输出格式\n###PATH:{PATH}\n{CODE}
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly. Based on the code in the project repository provided by the user and the user's requirements, generate new code or modify existing code. The output format is:\n###PATH: {PATH}\n {CODE}
```
1. Repository File Add, Delete, Modify Format
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly. Based on the code in the project repository provided by the user and the user's requirements, generate new code or modify existing code. The output format is:\n###PATH: {PATH}\n {CODE}<|user|>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
<<Query>><|assistant|>\n
```
2. Example:
- Prompt
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly. Based on the code in the project repository provided by the user and the user's requirements, generate new code or modify existing code. The output format is:\n###PATH: {PATH}\n {CODE}<|user|>
###PATH: sort.py
def quick_sort(arr):
if len(arr) <= 1:
return arr
needle = "codegeex4-all-9b"
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
###PATH: calculator.py
def calculate(a, b, op):
if op == '+':
return a + b
elif op == '-':
return a - b
elif op == '\*':
return a \* b
elif op == '/':
if b == 0:
return 'devider can not be 0'
else:
return a / b
else:
return 'error'
Write a new script for calculator to write a simple test|assistant|>\n
```
- Output
```
###PATH: test_calculator.py
import calculator
def test_calculator():
assert calculator.calculate(2, 3, '+') == 5
assert calculator.calculate(5, 2, '-') == 3
assert calculator.calculate(3, 4, '\*') == 12
assert calculator.calculate(10, 2, '/') == 5
assert calculator.calculate(10, 0, '/') == 'devider can not be 0'
assert calculator.calculate(10, 2, '%') == 'error'
test_calculator()
```

View File

@ -0,0 +1,191 @@

**项目级别使用教程,项目文件增删改,项目问答**
在项目级别任务中建议使用CodeGeeX4-ALL-9B-128k的模型版本该模型支持128k的上下文大约是1万行代码。
出于推理时间成本以及项目内容仍会超过128k的情况我们强烈建议在使用CodeGeeX4-ALL-9B-128k模型时对模型输出进行裁剪。
模型输出裁剪
- bm25&embedding召回
- 超过128k对输入进行截断这里注意需要保留主题special token<|system|>, <|user|>,<|assistant|>等)
- etc.
以下附上一个CodeGeeX4支持的语言列表您可以使用主要语言做为初步裁剪方式。
主要语言30种共支持310中语言
```
['c', 'c++', 'csharp', 'cuda', 'dart', 'go', 'haskell', 'html', 'java', 'javascript', 'json', 'kotlin', 'lua', 'markdown', 'objective-c++', 'pascal', 'php', 'python', 'r', 'ruby', 'rust', 'scala', 'shell', 'sql', 'swift', 'tex', 'txt', 'typescript', 'vue', 'xml']
```
<a name="heading_0"></a>**项目级别使用教程**
对模型输入进行处理后128k以内
我们需要特殊的输入格式激活模型的项目问答和项目文件增删改功能
<a name="heading_1"></a>1. **项目问答**
1. System Prompt
system prompt这里采用和问答一致的prompt同样这里我们支持中文和英文两种system prompt。中英文 system prompt不直接影响模型输出的语言您可以在system prompt的最后使用请用中文回答。/Please answer in English.)来诱导模型输出的语言
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.(请用中文回答。/Please answer in English.)
```
2. 项目问答输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。<|user|>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
<<用户Query>><|assistant|>\n
```
3. 例子
- 输入
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。<|user|>
###PATH: sort.py
def quick_sort(arr):
if len(arr) <= 1:
return arr
needle = "codegeex4-all-9b"
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
###PATH: calculator.py
def calculate(a, b, op):
if op == '+':
return a + b
elif op == '-':
return a - b
elif op == '*':
return a \* b
elif op == '/':
if b == 0:
return '除数不能为0'
else:
return a / b
else:
return '无效的运算符'
以上代码中needle的赋值是什么<|assistant|>\n
```
- 输出
```
根据以上代码needle的值是"codegeex4-all-9b"
```
<a name="heading_2"></a>2. **项目文件增删改**
1. System Prompt
在项目文件增删改这个任务上需要使用单独的system prompt。同样这里我们支持中文和英文两套system prompt。因为这里的模型输出代码所以system prompt中不建议加入诱导中英文回答的内容。
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码。请根据用户给出的项目仓库中的代码以及用户提出的需求生成新的代码或者更改已有代码。输出格式\n###PATH:{PATH}\n{CODE}
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly. Based on the code in the project repository provided by the user and the user's requirements, generate new code or modify existing code. The output format is:\n###PATH: {PATH}\n {CODE}
```
1. 项目问答输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码。请根据用户给出的项目仓库中的代码以及用户提出的需求生成新的代码或者更改已有代码。输出格式\n###PATH:{PATH}\n{CODE}<|user|>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
###PATH: <<File1 Path>>
<<File1 Code Content>>
<<用户Query>><|assistant|>\n
```
2. 例子
- 输入
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码。请根据用户给出的项目仓库中的代码以及用户提出的需求生成新的代码或者更改已有代码。输出格式\n###PATH:{PATH}\n{CODE}<|user|>
###PATH: sort.py
def quick_sort(arr):
if len(arr) <= 1:
return arr
needle = "codegeex4-all-9b"
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
###PATH: calculator.py
def calculate(a, b, op):
if op == '+':
return a + b
elif op == '-':
return a - b
elif op == '\*':
return a \* b
elif op == '/':
if b == 0:
return '除数不能为0'
else:
return a / b
else:
return '无效的运算符'
写一个新的脚本为calculator写一个简单测试<|assistant|>\n
```
- 输出
```
###PATH: test_calculator.py
import calculator
def test_calculator():
assert calculator.calculate(2, 3, '+') == 5
assert calculator.calculate(5, 2, '-') == 3
assert calculator.calculate(3, 4, '\*') == 12
assert calculator.calculate(10, 2, '/') == 5
assert calculator.calculate(10, 0, '/') == '除数不能为0'
assert calculator.calculate(10, 2, '%') == '无效的运算符'
test_calculator()
```

View File

@ -0,0 +1,372 @@
**System Prompt Tutorial: Plugin Features, Multi-Turn Conversations, Custom System Prompts**
This tutorial primarily introduces the system prompts for plugin features, the use of custom system prompts, and the strategy for maintaining historical information in multi-turn conversations.
Plugin features include: code comments, unit testing, code explanation, code translation, candidate questions, code fixing, code review, and file Q&A.
You can use the CodeGeeX4-ALL-9B-128k model and control memory requirements by setting different `max_length` values. For example, you can set `max_length` to 16k or 32k to run the model on consumer-grade graphics cards.
<a name="heading_0"></a>**System Prompt Usage Tutorial**
<a name="heading_1"></a>1. **Chat & General Mode**
- We support both Chinese and English system prompts. The system prompt language does not directly affect the model's output language. You can guide the model's output language by using phrases like "请用中文回答。" or "Please answer in English." at the end of the system prompt.
- Chinese system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.(请用中文回答。/Please answer in English.)
```
- Prompting Format
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。/Please answer in English.<|user|>
<<Query>><|assistant|>\n
```
- Example
``````
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.Please answer in English.<|user|>
Write a Quick sort in Python<|assistant|>
Quick Sort is a commonly used sorting algorithm with an average time complexity of O(nlogn). Below is an example of Quick Sort implemented in Python:
```python
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
```
``````
<a name="heading_2"></a>2. **Code Comments**
- We support both Chinese and English system prompts. The system prompt language does not directly affect the model's output language. You can guide the model's output language by using phrases like "请用中文回答。" or "Please answer in English." at the end of the system prompt. In the code comments scenario, Chinese and English correspond to the language used for the comments.
- Chinese system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请为输入代码提供格式规范的注释包含多行注释和单行注释请注意不要改动原始代码只需要添加注释。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please provide well-formatted comments for the given code, including both multi-line and single-line comments. Do not modify the original code, only add comments. Output only the code.(请用中文回答。/Please answer in English.
```
- Prompting Format
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please provide well-formatted comments for the given code, including both multi-line and single-line comments. Do not modify the original code, only add comments. Output only the code.<|user|>
<<Code Snippet>>
<<Query>><|assistant|>\n
```
<a name="heading_3"></a>3. **Code Explanation**
- We support both Chinese and English system prompts. The system prompt language does not directly affect the model's output language. You can guide the model's output language by using phrases like "请用中文回答。" or "Please answer in English." at the end of the system prompt.
- Chinese system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请解释输入代码的含义包括实现原理、用途和注意事项等。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please explain the meaning of the input code, including the implementation principle, purpose, and precautions.(请用中文回答。/Please answer in English.
```
- Prompting Format
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please explain the meaning of the input code, including the implementation principle, purpose, and precautions.<|user|>
<<Code Snippet>>
<<Query>>
Explain the above code snippet<|assistant|>\n
```
<a name="heading_4"></a>4. **Code Translation**
- We support both Chinese and English system prompts. Mixed Chinese and English output is not supported because the output consists only of code, and any comments within the code will follow the comments in the input code.
- Chinese system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请将输入代码翻译成目标语言需要满足目标语言的语法规范并保证功能正确性。目标语言{目标语言}。
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please translate the input code into the target language, ensuring that it adheres to the syntax rules of the target language and guarantees functional correctness. Target language: {target_language}.
```
- Prompting Format
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please translate the input code into the target language, ensuring that it adheres to the syntax rules of the target language and guarantees functional correctness. Target language: {target_language}.<|user|>
<<Code Snippet>>
translate the above code snippet into {target_language}, only output the translation result, without explanation.<|assistant|>\n
```
<a name="heading_5"></a>5. **Code Review**
- Currently, only Chinese output is supported. Alternatively, you can use the Chat & General Mode to construct your own system prompt to complete this task.
- Chinese system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请对输入代码进行仔细的审查如果有错误请指出并提出改进意见。
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please carefully review the input of `git diff` and propose improvements for syntax logic, code quality, code performance, and code security.
```
- Prompting Format
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please carefully review the input of `git diff` and propose improvements for syntax logic, code quality, code performance, and code security.<|user|>
<<Code Snippet>>
<<Query>><|assistant|>\n
```
<a name="heading_6"></a>6. **Code Fixing**
- We support both Chinese and English system prompts. Mixed Chinese and English output is not supported because the output consists only of code, and any comments within the code will follow the comments in the input code.
- Chinese system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请检查代码中潜在的bug并对代码进行修改请注意只针对代码进行修改没有必要不要修改注释输出修改后的代码。
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please check for potential bugs in the code and make modifications. Ensure that only the code is modified, and do not change the comments unless necessary. Output only the modified code.
```
- Prompting Format
```
<|system|>
answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please check for potential bugs in the code and make modifications. Ensure that only the code is modified, and do not change the comments unless necessary. Output only the modified code.<|user|>
<<Code Snippet>>
<<Query>><|assistant|>\n
```
<a name="heading_7"></a>7. **Unit Testing**
- We support both Chinese and English system prompts. Mixed Chinese and English output is not supported because the output consists only of code, and any comments within the code will follow the comments in the input code.
- Chinese system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请为输入代码生成单元测试保证测例的正确性并覆盖尽可能多的情况。
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please generate unit tests for the input code to ensure the correctness and accuracy of the test cases, and cover as many scenarios as possible to ensure better testing of corner cases. Output only the code.
```
- Prompting Format
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please generate unit tests for the input code to ensure the correctness and accuracy of the test cases, and cover as many scenarios as possible to ensure better testing of corner cases. Output only the code.<|user|>
<<Code Snippet>>
<<Query>><|assistant|>\n
```
<a name="heading_8"></a>8. **Candidate Questions**
- We support both Chinese and English system prompts. The system prompt language does not directly affect the model's output language. You can guide the model's output language by using phrases like "请用中文回答。" or "Please answer in English." at the end of the system prompt.
- Chinese system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请预测用户接下来会问的问题注意和历史记录相关。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer questions users have about programming, coding, and computers, and engage in dialogue by asking questions. Task: Based on the previous conversation, predict the next question the user is likely to ask. The question should be concise and align with the previous conversation content.(请用中文回答。/Please answer in English.
```
- Prompting Format
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer questions users have about programming, coding, and computers, and engage in dialogue by asking questions. Task: Based on the previous conversation, predict the next question the user is likely to ask. The question should be concise and align with the previous conversation content.<|user|>
<<user history 1>><|assistant|>
<<model output history 1>><|user|>
<<user history 2>><|assistant|>
<<model output history 2>><|user|>
<<user history 3>><|assistant|>
<<model output history 3>><|user|>
Based on the previous conversation, here's a programming-related question you can ask.<|assistant|>\n
```
<a name="heading_9"></a>9. **File Q&A**
- We support both Chinese and English system prompts. The system prompt language does not directly affect the model's output language. You can guide the model's output language by using phrases like "请用中文回答。" or "Please answer in English." at the end of the system prompt. We can use the Chat & General Mode system prompt to complete this task.
- Chinese system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请预测用户接下来会问的问题注意和历史记录相关。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer questions users have about programming, coding, and computers, and engage in dialogue by asking questions. Task: Based on the previous conversation, predict the next question the user is likely to ask. The question should be concise and align with the previous conversation content.(请用中文回答。/Please answer in English.
```
- 示例
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer questions users have about programming, coding, and computers, and engage in dialogue by asking questions. Task: Based on the previous conversation, predict the next question the user is likely to ask. The question should be concise and align with the previous conversation content.<|user|>
###PATH: sort.py
def quick_sort(arr):
if len(arr) <= 1:
return arr
needle = "codegeex4-all-9b"
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
what is needle value<|assistant|>\n
```
```
according to above code, the value of needle is "codegeex4-all-9b"
```
<a name="heading_10"></a>10. **Custom System Prompt**
- We support custom system prompts to provide a personalized experience for the open-source community and CodeGeeX users. Below is an example.
- Example
```
<|system|>
I want you to act as a Python console. I will input commands, and you will reply with what the console should display. I want you to reply only with the terminal output in a single, unique code block and nothing else. Do not write explanations. Do not enter commands unless I instruct you to do so. When I need to tell you something in English, I will put the text in curly brackets.<|user|>
for i in range(5):
print(i)
<|assistant|>\n
```
```
0
1
2
3
4
```
<a name="heading_11"></a>11. **Multi-Turn Conversations**
- For multi-turn conversations, we can use the Chat & General Mode as the system prompt. If a system prompt other than the Chat & General Mode is used in a multi-turn conversation, we recommend including the system prompt information in the same turn input. Below, we provide an example.
- Chinese system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.(请用中文回答。/Please answer in English.)
```
- Prompting Format
```
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.(请用中文回答。/Please answer in English.<|user|>
<<Query>><|assistant|>\n
```
- Example
`````
<|system|>
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.<|user|>
wirte a quick sort using python.<|assistant|>
Quick Sort is a commonly used sorting algorithm with an average time complexity of O(nlogn). Below is an example of Quick Sort implemented in Python:
```python
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
```
<|user|>
```python
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please provide well-formatted comments for the given code, including both multi-line and single-line comments. Do not modify the original code, only add comments. Output only the code.<|assistant|>
```python
# Quick Sort
def quick_sort(arr):
# Check if arr is empty, if so, return arr
if len(arr) <= 1:
return arr
# Choose a pivot value, here we select the middle value of the array
pivot = arr[len(arr) // 2]
# Place elements less than the pivot into a new array
left = [x for x in arr if x < pivot]
# Place elements equal to the pivot into a new array
middle = [x for x in arr if x == pivot]
# Place elements greater than the pivot into a new array
right = [x for x in arr if x > pivot]
# Recursively quick sort the left and right arrays and merge the results
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
```
<|user|>
who are u<|assistant|>
I am an AI programming assistant named CodeGeeX, developed jointly by the KEG Lab at Tsinghua University and Zhipu AI. I can perform code generation and completion, automatically add comments, translate code, and provide intelligent Q&A. These features can significantly help developers improve their programming efficiency.<|user|>
Based on the previous conversation, here's a programming-related question you can ask.<|assistant|>\n
``````

View File

@ -0,0 +1,374 @@
**System Prompt使用教程插件功能多轮对话自定义System Prompt**
本篇教程中主要介绍了插件功能的system prompt自定义system prompt的使用以及多轮对话的历史信息的维护策略。
插件功能包括:代码注释,单元测试,代码解释,代码翻译,候选问题,代码修复,代码审查,文件问答。
您可以使用CodeGeeX4-ALL-9B-128k模型通过设置不同的max_length控制对显存的需求。例如您可以将max_length设置在16k或者32k以便将模型跑在消费级显卡上
<a name="heading_0"></a>**System Prompt 使用教程**
<a name="heading_1"></a>1. **Chat&通用模式**
- 我们支持中文和英文两种system prompt。中英文system prompt不直接影响模型输出的语言您可以在system prompt的最后使用请用中文回答。/Please answer in English.)来引导模型输出的语言
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.(请用中文回答。/Please answer in English.)
```
- 输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。/Please answer in English.<|user|>
<<用户Query>><|assistant|>\n
```
- 例子
``````
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。<|user|>
用python写一个快速排序<|assistant|>
快速排序Quick Sort是一种常用的排序算法其平均时间复杂度为 O(nlogn)。下面是一个使用 Python 实现的快速排序示例:
```python
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
```
``````
<a name="heading_2"></a>2. **代码注释**
- 我们支持中文和英文两种system prompt。中英文system prompt不直接影响模型输出的语言您可以在system prompt的最后使用请用中文回答。/Please answer in English.)来引导模型输出的语言。在代码注释场景中,中英文对应的是注释部分的语言
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请为输入代码提供格式规范的注释包含多行注释和单行注释请注意不要改动原始代码只需要添加注释。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please provide well-formatted comments for the given code, including both multi-line and single-line comments. Do not modify the original code, only add comments. Output only the code.(请用中文回答。/Please answer in English.
```
- 输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请为输入代码提供格式规范的注释包含多行注释和单行注释请注意不要改动原始代码只需要添加注释。<|user|>
<<代码块>>
<<自定义Query>><|assistant|>
#此处有\n
```
<a name="heading_3"></a>3. **代码解释**
- 我们支持中文和英文两种system prompt。中英文system prompt不直接影响模型输出的语言您可以在system prompt的最后使用请用中文回答。/Please answer in English.)来引导模型输出的语言
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请解释输入代码的含义包括实现原理、用途和注意事项等。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please explain the meaning of the input code, including the implementation principle, purpose, and precautions.(请用中文回答。/Please answer in English.
```
- 输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请解释输入代码的含义包括实现原理、用途和注意事项等。<|user|>
<<代码块>>
<<自定义Query>>
解释以上代码<|assistant|>\n
```
<a name="heading_4"></a>4. **代码翻译**
- 我们支持中文和英文两种system prompt。不支持中英文输出因为输出仅有代码代码内的注释会跟随输入代码中的注释
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请将输入代码翻译成目标语言需要满足目标语言的语法规范并保证功能正确性。目标语言{目标语言}。
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please translate the input code into the target language, ensuring that it adheres to the syntax rules of the target language and guarantees functional correctness. Target language: {target_language}.
```
- 输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请将输入代码翻译成目标语言需要满足目标语言的语法规范并保证功能正确性。目标语言{目标语言}。<|user|>
<<代码块>>
把这段代码翻译成{目标语言},只输出翻译结果,不要解释:<|assistant|>\n
```
<a name="heading_5"></a>5. **代码审查**
- 暂时只支持中文输出,或者您可以用聊天&通用模式自己构建system prompt完成此任务
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请对输入代码进行仔细的审查如果有错误请指出并提出改进意见。
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please carefully review the input of `git diff` and propose improvements for syntax logic, code quality, code performance, and code security.
```
- 输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请对git diff输入或代码函数进行仔细的审查并对语法逻辑代码质量代码性能和代码安全提出改进意见。<|user|>
<<代码块>>
<<自定义Query>><|assistant|>\n
```
<a name="heading_6"></a>6. **代码修复**
- 我们支持中文和英文两种system prompt。不支持中英文输出因为输出仅有代码代码内的注释会跟随输入代码中的注释
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请检查代码中潜在的bug并对代码进行修改请注意只针对代码进行修改没有必要不要修改注释输出修改后的代码。
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please check for potential bugs in the code and make modifications. Ensure that only the code is modified, and do not change the comments unless necessary. Output only the modified code.
```
- 输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请为输入代码生成单元测试保证测例的正确性并覆盖尽可能多的情况。仅输出代码。<|user|>
<<代码块>>
<<自定义Query>><|assistant|>\n
```
<a name="heading_7"></a>7. **单元测试**
- 我们支持中文和英文两种system prompt。不支持中英文输出因为输出仅有代码代码内的注释会跟随输入代码中的注释
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请为输入代码生成单元测试保证测例的正确性并覆盖尽可能多的情况。
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary. Task: Please generate unit tests for the input code to ensure the correctness and accuracy of the test cases, and cover as many scenarios as possible to ensure better testing of corner cases. Output only the code.
```
- 输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请为输入代码生成单元测试保证测例的正确性并覆盖尽可能多的情况。仅输出代码。<|user|>
<<代码块>>
<<自定义Query>><|assistant|>\n
```
<a name="heading_8"></a>8. **候选问题**
- 我们支持中文和英文两种system prompt。中英文system prompt不直接影响模型输出的语言您可以在system prompt的最后使用请用中文回答。/Please answer in English.)来引导模型输出的语言
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请预测用户接下来会问的问题注意和历史记录相关。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer questions users have about programming, coding, and computers, and engage in dialogue by asking questions. Task: Based on the previous conversation, predict the next question the user is likely to ask. The question should be concise and align with the previous conversation content.(请用中文回答。/Please answer in English.
```
- 输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务根据聊天内容预测用户接下来会问的问题问题需要简短且有推荐意义。<|user|>
<<历史用户输入1>><|assistant|>
<<历史模型输出1>><|user|>
<<历史用户输入2>><|assistant|>
<<历史模型输出2>><|user|>
<<历史用户输入3>><|assistant|>
<<历史模型输出3>><|user|>
请根据以上对话,生成一个我可以提问的,且与之前对话和编程相关的问题。<|assistant|>
#此处有\n<|assistant|>\n
```
<a name="heading_9"></a>9. **文件问答**
- 我们支持中文和英文两种system prompt。中英文system prompt不直接影响模型输出的语言您可以在system prompt的最后使用请用中文回答。/Please answer in English.来引导模型输出的语言。我们可以使用Chat&通用模式的system prompt来完成此项任务。
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请预测用户接下来会问的问题注意和历史记录相关。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer questions users have about programming, coding, and computers, and engage in dialogue by asking questions. Task: Based on the previous conversation, predict the next question the user is likely to ask. The question should be concise and align with the previous conversation content.(请用中文回答。/Please answer in English.
```
- 示例
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。<|user|>
###PATH: sort.py
def quick_sort(arr):
if len(arr) <= 1:
return arr
needle = "codegeex4-all-9b"
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
needle的赋值是什么<|assistant|>\n
```
```
根据以上代码needle的值是"codegeex4-all-9b"
```
<a name="heading_10"></a>10. **自定义 system prompt**
- 我们支持自定义的system prompt为开源社区的小伙伴以及codegeex的用户提供个性化使用体验。以下是一个示例。
- 例子
```
<|system|>
我希望你充当一个 python 控制台。我将输入命令,你将回复控制台应该显示的内容。我希望你只在一个独特的代码块中回复终端输出,除此之外什么也不要写。不要写解释。除非我指示你这么做,否则不要输入命令。当我需要用英文告诉你一些事情时,我会把文本放在大括号里<|user|>
for i in range(5):
print(i)
<|assistant|>\n
```
```
0
1
2
3
4
```
<a name="heading_11"></a>11. **多轮对话**
- 多轮对话我们可以使用Chat&通用模式做为system prompt如果多轮对话中使用了除Chat&通用模式外的system prompt我们建议您将system promt的信息放入同轮次<|user|>输入中。以下我们给出一个示例。
- 中文system prompt
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。/Please answer in English.
```
- English system prompt
```
You are an intelligent programming assistant named CodeGeeX. You will answer any questions users have about programming, coding, and computers, and provide code that is formatted correctly, executable, accurate, and secure, and offer detailed explanations when necessary.(请用中文回答。/Please answer in English.)
```
- 输入格式
```
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。请用中文回答。/Please answer in English.<|user|>
<<用户Query>><|assistant|>\n
```
- 例子
`````
<|system|>
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务根据聊天内容预测用户接下来会问的问题问题需要简短且有推荐意义。<|user|>
用python写一个快速排序<|assistant|>
快速排序Quick Sort是一种常用的排序算法其平均时间复杂度为 O(nlogn)。下面是一个使用 Python 实现的快速排序示例:
```python
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
```
<|user|>
```python
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
```
你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。任务请为输入代码提供格式规范的注释包含多行注释和单行注释请注意不要改动原始代码只需要添加注释。<|assistant|>
```python
# 快速排序
def quick_sort(arr):
# 判断arr是否为空如果是空就返回arr
if len(arr) <= 1:
return arr
# 选择一个基准值,这里我们选择数组中间的值
pivot = arr[len(arr) // 2]
# 将数组中小于基准值的元素放到一个新数组中
left = [x for x in arr if x < pivot]
# 将数组中等于基准值的元素放到一个新数组中
middle = [x for x in arr if x == pivot]
# 将数组中大于基准值的元素放到一个新数组中
right = [x for x in arr if x > pivot]
# 递归地对左右两个数组进行快速排序,并将结果合并
return quick_sort(left) + middle + quick_sort(right)
arr = [3,6,8,10,1,2,1]
print(quick_sort(arr))
```
<|user|>
你是谁<|assistant|>
我是一个名为 CodeGeeX 的AI编程助手是由清华大学KEG实验室和智谱AI公司共同开发的。我可以实现代码的生成与补全、自动添加注释、代码翻译以及智能问答等功能能够帮助开发者显著提高编程效率。<|user|>
请根据以上对话,生成一个我可以提问的,且与之前对话和编程相关的问题。<|assistant|>\n
``````

View File

@ -0,0 +1,62 @@
FROM python:3.11-slim-bookworm
WORKDIR /mnt/data
RUN apt-get update && apt-get install -y \
gcc \
libffi-dev \
zlib1g-dev \
fonts-arphic-ukai \
fonts-arphic-uming \
fonts-ipafont-mincho \
fonts-ipafont-gothic \
fonts-unfonts-core \
libgdal-dev \
g++ \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir \
pydantic \
tornado \
jupyter_client \
ipython \
ipykernel \
numpy \
pandas \
scipy \
matplotlib \
scikit-learn \
notebook \
beautifulsoup4 \
seaborn \
pytest \
ipywidgets \
sympy \
statsmodels \
joblib \
cython \
lxml \
xlrd \
qrcode \
nltk \
opencv-python \
Pillow \
geopandas
ENV HOME=/mnt/data
RUN find / -perm +6000 -type f -exec chmod a-s {} \; || true
RUN echo "set -o history -o vi" >> /etc/profile
RUN useradd -u 999 -ms /bin/bash appuser
RUN chown -R appuser:appuser /mnt/data
USER appuser
ENV JUPYTER_RUNTIME_DIR=/mnt/data/.local/share/jupyter/runtime
ENV JUPYTER_DATA_DIR=/mnt/data/.local/share/jupyter
ENV JUPYTER_CONFIG_DIR=/mnt/data/.jupyter
COPY sandbox.py /sandbox.py
VOLUME [ "/mnt/data" ]
CMD ["python", "/sandbox.py"]

View File

@ -0,0 +1,28 @@
# Codegeex4 Interpreter Gradio
Fully local gradio demo of CodeGeeX4 Interpreter.
## Usage
### Install Dependencies
```python
pip install gradio requests
```
### Build & Launch Sandbox
```bash
docker build -t sandbox -f Dockerfile.sandbox .
docker run --name sandbox --publish 8080:8080 sandbox
```
### Launch Demo
```bash
python app.py --tgi-addr <tgi-addr>
```
## Docs
Check out the [documentation](./SANDBOX.md) for the sandbox API.

View File

@ -0,0 +1,28 @@
# Codegeex4 代码解释器DEMO
完全本地可运行的 CodeGeeX4 代码解释器.
## 使用方法
### 安装依赖
```python
pip install gradio requests
```
### 构建并启动本地沙盒环境
```bash
docker build -t sandbox -f Dockerfile.sandbox .
docker run --name sandbox --publish 8080:8080 sandbox
```
### 启动DEMO
```bash
python app.py --tgi-addr <tgi-addr>
```
## 文档
参考 [沙盒API文档](./SANDBOX.md)。

136
interpreter_demo/SANDBOX.md Normal file
View File

@ -0,0 +1,136 @@
# Sandbox API
### Ping
**Path:** GET `/`
Check whether a sandbox is alive and return information about it.
#### Request
-
#### Response
**Status:**
- `200` if alive
**Example:**
```json
{
"last_activity": "2006-01-02T15:04:05Z07:00", // RFC 3339
}
```
### Execute
**Path:** POST `/execute`
#### Request
**Content-Type:** `application/json`
**JSON Schema:**
| Name | Type | Description |
| -------------- | ----------------- | ------------------------------------------------------------------------------------------------------ |
| `code` | string | The code to be executed. |
| `timeout_secs` | number (Optional) | Abort execution after timeout. Does not include environment and runtime creation time. Defaults to 60. |
#### Response
**Status:**
- `200` if successful
**Content-Type:** `application/json`
**Example:**
```json
{
"status": "ok", // Possible values: "ok", "timeout"
"events": [
{
"type": "stream",
"timestamp": "2006-01-02T15:04:05Z07:00", // RFC 3339
"data": {
"name": "stdout", // Possible values: "stdout", "stderr"
"text": "Hello World!",
}
},
{
"type": "display_data",
"timestamp": "2006-01-02T15:04:05Z07:00", // RFC 3339
"data": {
"variants": {
"text/plain": "<IPython.core.display.Image object>",
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4//8/AAX+Av4N70a4AAAAAElFTkSuQmCC" // Base64 encoded PNG image
}
}
},
{
"type": "file", // The program has written a file to disk.
"timestamp": "2006-01-02T15:04:05Z07:00", // RFC 3339
"data": {
"path": "README.md",
"size": 128, // Size is expressed in bytes
}
},
{
"type": "error",
"timestamp": "2006-01-02T15:04:05Z07:00", // RFC 3339
"data": {
"ename": "ZeroDivisionError",
"evalue": "division by zero",
"traceback": [
"\\u001b[0;31m---------------------------------------------------------------------------\\u001b[0m",
"\\u001b[0;31mZeroDivisionError\\u001b[0m Traceback (most recent call last)",
"Cell \\u001b[0;32mIn[1], line 2\\u001b[0m\\n\\u001b[1;32m 1\\u001b[0m \\u001b[38;5;66;03m# \\u8ba1\\u7b97\\u8868\\u8fbe\\u5f0f\\u7684\\u7ed3\\u679c\\u001b[39;00m\\n\\u001b[0;32m----> 2\\u001b[0m result \\u001b[38;5;241m=\\u001b[39m \\u001b[38;5;241;43m361234\\u001b[39;49m\\u001b[43m \\u001b[49m\\u001b[38;5;241;43m/\\u001b[39;49m\\u001b[43m \\u001b[49m\\u001b[38;5;241;43m0\\u001b[39;49m \\u001b[38;5;241m+\\u001b[39m \\u001b[38;5;241m4514\\u001b[39m \\u001b[38;5;241m*\\u001b[39m \\u001b[38;5;241m1234\\u001b[39m \\u001b[38;5;241m-\\u001b[39m \\u001b[38;5;241m27152346\\u001b[39m \\u001b[38;5;241m/\\u001b[39m \\u001b[38;5;241m2023\\u001b[39m\\n\\u001b[1;32m 3\\u001b[0m result\\n",
"\\u001b[0;31mZeroDivisionError\\u001b[0m: division by zero"
]
}
}
]
}
```
### File upload
**Path:** POST `/files/upload/-/*path`
Upload a file to the sandbox under `*path`.
#### Request
**Content-Length:** The length of the file in bytes.
**Body:** The raw contents of the file as bytes.
#### Response
**Status:**
- `201` if upload was successful
- `409` if file already exists
### File download
**Path:** GET `/files/download/-/*path`
Download a file from the sandbox from `*path`.
#### Request
\-
#### Response
**Content-Type:** Automatically detected, depending on the file.
**Content-Disposition:** `attachment; filename*=UTF-8''<filename>`
**Body:** The raw contents of the file.
**Status:**
- `200` if file exists
- `404` if file is not found

208
interpreter_demo/app.py Normal file
View File

@ -0,0 +1,208 @@
import argparse
import json
import os
import re
from typing import Any, Dict, List, Tuple
import gradio as gr
import requests
SYSTEM_PROMPT = {
"zh": "你是一位智能编程助手你叫CodeGeeX你连接着一台电脑但请注意不能联网。在使用Python解决任务时你可以运行代码并得到结果如果运行结果有错误你需要尽可能对代码进行改进。你可以处理用户上传到电脑上的文件文件默认存储路径是/mnt/data/。",
"en": "You are an intelligent programming assistant named CodeGeeX, connected to a computer, but please note that you cannot access the internet. When solving tasks using Python, you can run code and obtain results. If there are any errors in the results, you need to improve the code as much as possible. You can also handle files uploaded to the computer, with the default storage path being /mnt/data/.",
}
CODEGEEX_SPECIAL_TOKENS = {
"user": "<|user|>",
"assistant": "<|assistant|>",
"system": "<|system|>",
"observation": "<|observation|>",
"eos": "<|endoftext|>",
}
parser = argparse.ArgumentParser(description="CodeGeeX4 Interpreter")
parser.add_argument("--tgi-addr", type=str, required=True)
parser.add_argument("--sandbox-addr", type=str, default="http://127.0.0.1:8080")
parser.add_argument("--temperature", type=float, default=0.2)
parser.add_argument("--top-p", type=float, default=0.95)
args = parser.parse_args()
code_block_regex = re.compile(r"```(.*?)\n(.*?)```", re.DOTALL)
def execute_code_block(lang, code) -> Tuple[List[Dict[str, Any]], str]:
assert lang in ["python"]
response = requests.post(
f"{args.sandbox_addr}/execute",
json={"code": code, "timeout_secs": 60},
)
response = response.json()
print(f"[RESPONSE] {response}")
return response["events"], response["status"]
def upload_file(filepath: str, contents: str):
print(f"[REQUEST] Upload {filepath} ({len(contents)} bytes)")
response = requests.post(
f"{args.sandbox_addr}/files/upload/-/{filepath.lstrip('/')}",
data=bytes(contents, encoding="utf-8"),
)
print(f"[RESPONSE] {response.text}")
assert response.status_code == 201
def stream_chat_completion(message, history):
should_stop = False
round = 0
max_rounds = 5
file_info = ""
for filepath in message.get("files", []):
with open(filepath, "r") as f:
contents = f.read()
filename = os.path.basename(filepath)
upload_file(f"/mnt/data/{filename}", contents)
file_info += f"# File: /mnt/data/{filename}\n"
file_info += f"# Size: {len(contents)}\n"
file_info += "# File uploaded\n"
prompt = f"{CODEGEEX_SPECIAL_TOKENS['system']}\n{SYSTEM_PROMPT['en']}\n"
for [user_message, bot_message] in history:
if isinstance(user_message, tuple):
# It's a file
pass
else:
# Remove any '![image](data:image/png;base64,...)' from the bot message.
bot_message = re.sub(
r"!\[image\]\(data:image/png;base64,[^\)]+\)", "", bot_message
)
prompt += f"{CODEGEEX_SPECIAL_TOKENS['user']}\n{user_message}\n"
prompt += f"{CODEGEEX_SPECIAL_TOKENS['assistant']}\n{bot_message}\n"
prompt += f"{CODEGEEX_SPECIAL_TOKENS['user']}\n{file_info}{message['text']}\n"
prompt += f"{CODEGEEX_SPECIAL_TOKENS['assistant']}\n"
stop_sequences = [
CODEGEEX_SPECIAL_TOKENS["eos"],
CODEGEEX_SPECIAL_TOKENS["user"],
CODEGEEX_SPECIAL_TOKENS["observation"],
]
while not should_stop and round < max_rounds:
round += 1
request_json_body = {
"inputs": prompt,
"parameters": {
"max_new_tokens": 2048,
"do_sample": True,
"top_p": args.top_p,
"temperature": args.temperature,
"stop": stop_sequences,
"details": True,
"stream": False,
},
}
print(f"[REQUEST] {request_json_body}")
response = requests.post(
f"{args.tgi_addr}/generate_stream",
json=request_json_body,
stream=True,
)
completion = ""
for line in response.iter_lines():
if line:
event = line.decode("utf-8")
if event.startswith("data:"):
event = event[5:].strip()
event = json.loads(event)
token = event["token"]["text"]
completion += token
prompt += token
# Only display the token if it's not "special".
if event["token"]["text"] not in CODEGEEX_SPECIAL_TOKENS.values():
yield token
# If the model asks for the code to be executed, do it.
if event["token"]["text"] == CODEGEEX_SPECIAL_TOKENS["observation"]:
match = code_block_regex.search(completion)
if match is None:
# Hm, it seems the model didn't write any code.
# Let's gently warn it.
prompt += f"\n```result\nError: no code to execute.\n```\n{CODEGEEX_SPECIAL_TOKENS['assistant']}\n"
yield "```\nError: no code to execute.\n```\n"
break
lang, code = match.groups()
events, status = execute_code_block(lang, code)
buffer = []
for exec_event in events:
if exec_event["type"] == "stream":
buffer.append(exec_event["text"])
if exec_event["type"] == "display_data":
if "text/plain" in exec_event["data"]["variants"]:
buffer.append(
exec_event["data"]["variants"]["text/plain"]
)
if status == "timeout":
buffer.append("Execution timed out.")
if status == "error":
buffer.append("Execution failed.")
prompt += f"\n```result\n{''.join(buffer)}\n```\n{CODEGEEX_SPECIAL_TOKENS['assistant']}\n"
yield f"```\n{''.join(buffer)}\n```\n"
for exec_event in events:
if exec_event["type"] == "display_data":
if "image/png" in exec_event["data"]["variants"]:
yield f"![image](data:image/png;base64,{exec_event['data']['variants']['image/png']})"
elif "text/html" in exec_event["data"]["variants"]:
yield exec_event["data"]["variants"]["text/html"]
break
# If the model otherwise ends the generation, stop here.
if event["details"] is not None:
should_stop = True
break
print(f"[RESPONSE] {completion}")
def predict(message: Dict[str, Any], history: List[List[str | None | tuple]]):
completion = ""
for delta in stream_chat_completion(message, history):
completion += delta
# Replace (sandbox:/ by (<sandbox-address>/
completion = completion.replace(
"sandbox:/", f"{args.sandbox_addr}/files/download/-/"
)
yield completion
demo = gr.ChatInterface(
fn=predict,
title="CodeGeeX4 Interpreter",
description="",
examples=[
{"text": "Compute factorial of 21 using code", "files": []},
{
"text": "Plot the class distribution of this dataset",
"files": ["./data.csv"],
},
{
"text": 'Reverse the following string and save it to a file: "9738426487936"',
"files": [],
},
],
multimodal=True,
)
demo.launch()

151
interpreter_demo/data.csv Normal file
View File

@ -0,0 +1,151 @@
"sepal.length","sepal.width","petal.length","petal.width","variety"
5.1,3.5,1.4,.2,"Setosa"
4.9,3,1.4,.2,"Setosa"
4.7,3.2,1.3,.2,"Setosa"
4.6,3.1,1.5,.2,"Setosa"
5,3.6,1.4,.2,"Setosa"
5.4,3.9,1.7,.4,"Setosa"
4.6,3.4,1.4,.3,"Setosa"
5,3.4,1.5,.2,"Setosa"
4.4,2.9,1.4,.2,"Setosa"
4.9,3.1,1.5,.1,"Setosa"
5.4,3.7,1.5,.2,"Setosa"
4.8,3.4,1.6,.2,"Setosa"
4.8,3,1.4,.1,"Setosa"
4.3,3,1.1,.1,"Setosa"
5.8,4,1.2,.2,"Setosa"
5.7,4.4,1.5,.4,"Setosa"
5.4,3.9,1.3,.4,"Setosa"
5.1,3.5,1.4,.3,"Setosa"
5.7,3.8,1.7,.3,"Setosa"
5.1,3.8,1.5,.3,"Setosa"
5.4,3.4,1.7,.2,"Setosa"
5.1,3.7,1.5,.4,"Setosa"
4.6,3.6,1,.2,"Setosa"
5.1,3.3,1.7,.5,"Setosa"
4.8,3.4,1.9,.2,"Setosa"
5,3,1.6,.2,"Setosa"
5,3.4,1.6,.4,"Setosa"
5.2,3.5,1.5,.2,"Setosa"
5.2,3.4,1.4,.2,"Setosa"
4.7,3.2,1.6,.2,"Setosa"
4.8,3.1,1.6,.2,"Setosa"
5.4,3.4,1.5,.4,"Setosa"
5.2,4.1,1.5,.1,"Setosa"
5.5,4.2,1.4,.2,"Setosa"
4.9,3.1,1.5,.2,"Setosa"
5,3.2,1.2,.2,"Setosa"
5.5,3.5,1.3,.2,"Setosa"
4.9,3.6,1.4,.1,"Setosa"
4.4,3,1.3,.2,"Setosa"
5.1,3.4,1.5,.2,"Setosa"
5,3.5,1.3,.3,"Setosa"
4.5,2.3,1.3,.3,"Setosa"
4.4,3.2,1.3,.2,"Setosa"
5,3.5,1.6,.6,"Setosa"
5.1,3.8,1.9,.4,"Setosa"
4.8,3,1.4,.3,"Setosa"
5.1,3.8,1.6,.2,"Setosa"
4.6,3.2,1.4,.2,"Setosa"
5.3,3.7,1.5,.2,"Setosa"
5,3.3,1.4,.2,"Setosa"
7,3.2,4.7,1.4,"Versicolor"
6.4,3.2,4.5,1.5,"Versicolor"
6.9,3.1,4.9,1.5,"Versicolor"
5.5,2.3,4,1.3,"Versicolor"
6.5,2.8,4.6,1.5,"Versicolor"
5.7,2.8,4.5,1.3,"Versicolor"
6.3,3.3,4.7,1.6,"Versicolor"
4.9,2.4,3.3,1,"Versicolor"
6.6,2.9,4.6,1.3,"Versicolor"
5.2,2.7,3.9,1.4,"Versicolor"
5,2,3.5,1,"Versicolor"
5.9,3,4.2,1.5,"Versicolor"
6,2.2,4,1,"Versicolor"
6.1,2.9,4.7,1.4,"Versicolor"
5.6,2.9,3.6,1.3,"Versicolor"
6.7,3.1,4.4,1.4,"Versicolor"
5.6,3,4.5,1.5,"Versicolor"
5.8,2.7,4.1,1,"Versicolor"
6.2,2.2,4.5,1.5,"Versicolor"
5.6,2.5,3.9,1.1,"Versicolor"
5.9,3.2,4.8,1.8,"Versicolor"
6.1,2.8,4,1.3,"Versicolor"
6.3,2.5,4.9,1.5,"Versicolor"
6.1,2.8,4.7,1.2,"Versicolor"
6.4,2.9,4.3,1.3,"Versicolor"
6.6,3,4.4,1.4,"Versicolor"
6.8,2.8,4.8,1.4,"Versicolor"
6.7,3,5,1.7,"Versicolor"
6,2.9,4.5,1.5,"Versicolor"
5.7,2.6,3.5,1,"Versicolor"
5.5,2.4,3.8,1.1,"Versicolor"
5.5,2.4,3.7,1,"Versicolor"
5.8,2.7,3.9,1.2,"Versicolor"
6,2.7,5.1,1.6,"Versicolor"
5.4,3,4.5,1.5,"Versicolor"
6,3.4,4.5,1.6,"Versicolor"
6.7,3.1,4.7,1.5,"Versicolor"
6.3,2.3,4.4,1.3,"Versicolor"
5.6,3,4.1,1.3,"Versicolor"
5.5,2.5,4,1.3,"Versicolor"
5.5,2.6,4.4,1.2,"Versicolor"
6.1,3,4.6,1.4,"Versicolor"
5.8,2.6,4,1.2,"Versicolor"
5,2.3,3.3,1,"Versicolor"
5.6,2.7,4.2,1.3,"Versicolor"
5.7,3,4.2,1.2,"Versicolor"
5.7,2.9,4.2,1.3,"Versicolor"
6.2,2.9,4.3,1.3,"Versicolor"
5.1,2.5,3,1.1,"Versicolor"
5.7,2.8,4.1,1.3,"Versicolor"
6.3,3.3,6,2.5,"Virginica"
5.8,2.7,5.1,1.9,"Virginica"
7.1,3,5.9,2.1,"Virginica"
6.3,2.9,5.6,1.8,"Virginica"
6.5,3,5.8,2.2,"Virginica"
7.6,3,6.6,2.1,"Virginica"
4.9,2.5,4.5,1.7,"Virginica"
7.3,2.9,6.3,1.8,"Virginica"
6.7,2.5,5.8,1.8,"Virginica"
7.2,3.6,6.1,2.5,"Virginica"
6.5,3.2,5.1,2,"Virginica"
6.4,2.7,5.3,1.9,"Virginica"
6.8,3,5.5,2.1,"Virginica"
5.7,2.5,5,2,"Virginica"
5.8,2.8,5.1,2.4,"Virginica"
6.4,3.2,5.3,2.3,"Virginica"
6.5,3,5.5,1.8,"Virginica"
7.7,3.8,6.7,2.2,"Virginica"
7.7,2.6,6.9,2.3,"Virginica"
6,2.2,5,1.5,"Virginica"
6.9,3.2,5.7,2.3,"Virginica"
5.6,2.8,4.9,2,"Virginica"
7.7,2.8,6.7,2,"Virginica"
6.3,2.7,4.9,1.8,"Virginica"
6.7,3.3,5.7,2.1,"Virginica"
7.2,3.2,6,1.8,"Virginica"
6.2,2.8,4.8,1.8,"Virginica"
6.1,3,4.9,1.8,"Virginica"
6.4,2.8,5.6,2.1,"Virginica"
7.2,3,5.8,1.6,"Virginica"
7.4,2.8,6.1,1.9,"Virginica"
7.9,3.8,6.4,2,"Virginica"
6.4,2.8,5.6,2.2,"Virginica"
6.3,2.8,5.1,1.5,"Virginica"
6.1,2.6,5.6,1.4,"Virginica"
7.7,3,6.1,2.3,"Virginica"
6.3,3.4,5.6,2.4,"Virginica"
6.4,3.1,5.5,1.8,"Virginica"
6,3,4.8,1.8,"Virginica"
6.9,3.1,5.4,2.1,"Virginica"
6.7,3.1,5.6,2.4,"Virginica"
6.9,3.1,5.1,2.3,"Virginica"
5.8,2.7,5.1,1.9,"Virginica"
6.8,3.2,5.9,2.3,"Virginica"
6.7,3.3,5.7,2.5,"Virginica"
6.7,3,5.2,2.3,"Virginica"
6.3,2.5,5,1.9,"Virginica"
6.5,3,5.2,2,"Virginica"
6.2,3.4,5.4,2.3,"Virginica"
5.9,3,5.1,1.8,"Virginica"
1 sepal.length sepal.width petal.length petal.width variety
2 5.1 3.5 1.4 .2 Setosa
3 4.9 3 1.4 .2 Setosa
4 4.7 3.2 1.3 .2 Setosa
5 4.6 3.1 1.5 .2 Setosa
6 5 3.6 1.4 .2 Setosa
7 5.4 3.9 1.7 .4 Setosa
8 4.6 3.4 1.4 .3 Setosa
9 5 3.4 1.5 .2 Setosa
10 4.4 2.9 1.4 .2 Setosa
11 4.9 3.1 1.5 .1 Setosa
12 5.4 3.7 1.5 .2 Setosa
13 4.8 3.4 1.6 .2 Setosa
14 4.8 3 1.4 .1 Setosa
15 4.3 3 1.1 .1 Setosa
16 5.8 4 1.2 .2 Setosa
17 5.7 4.4 1.5 .4 Setosa
18 5.4 3.9 1.3 .4 Setosa
19 5.1 3.5 1.4 .3 Setosa
20 5.7 3.8 1.7 .3 Setosa
21 5.1 3.8 1.5 .3 Setosa
22 5.4 3.4 1.7 .2 Setosa
23 5.1 3.7 1.5 .4 Setosa
24 4.6 3.6 1 .2 Setosa
25 5.1 3.3 1.7 .5 Setosa
26 4.8 3.4 1.9 .2 Setosa
27 5 3 1.6 .2 Setosa
28 5 3.4 1.6 .4 Setosa
29 5.2 3.5 1.5 .2 Setosa
30 5.2 3.4 1.4 .2 Setosa
31 4.7 3.2 1.6 .2 Setosa
32 4.8 3.1 1.6 .2 Setosa
33 5.4 3.4 1.5 .4 Setosa
34 5.2 4.1 1.5 .1 Setosa
35 5.5 4.2 1.4 .2 Setosa
36 4.9 3.1 1.5 .2 Setosa
37 5 3.2 1.2 .2 Setosa
38 5.5 3.5 1.3 .2 Setosa
39 4.9 3.6 1.4 .1 Setosa
40 4.4 3 1.3 .2 Setosa
41 5.1 3.4 1.5 .2 Setosa
42 5 3.5 1.3 .3 Setosa
43 4.5 2.3 1.3 .3 Setosa
44 4.4 3.2 1.3 .2 Setosa
45 5 3.5 1.6 .6 Setosa
46 5.1 3.8 1.9 .4 Setosa
47 4.8 3 1.4 .3 Setosa
48 5.1 3.8 1.6 .2 Setosa
49 4.6 3.2 1.4 .2 Setosa
50 5.3 3.7 1.5 .2 Setosa
51 5 3.3 1.4 .2 Setosa
52 7 3.2 4.7 1.4 Versicolor
53 6.4 3.2 4.5 1.5 Versicolor
54 6.9 3.1 4.9 1.5 Versicolor
55 5.5 2.3 4 1.3 Versicolor
56 6.5 2.8 4.6 1.5 Versicolor
57 5.7 2.8 4.5 1.3 Versicolor
58 6.3 3.3 4.7 1.6 Versicolor
59 4.9 2.4 3.3 1 Versicolor
60 6.6 2.9 4.6 1.3 Versicolor
61 5.2 2.7 3.9 1.4 Versicolor
62 5 2 3.5 1 Versicolor
63 5.9 3 4.2 1.5 Versicolor
64 6 2.2 4 1 Versicolor
65 6.1 2.9 4.7 1.4 Versicolor
66 5.6 2.9 3.6 1.3 Versicolor
67 6.7 3.1 4.4 1.4 Versicolor
68 5.6 3 4.5 1.5 Versicolor
69 5.8 2.7 4.1 1 Versicolor
70 6.2 2.2 4.5 1.5 Versicolor
71 5.6 2.5 3.9 1.1 Versicolor
72 5.9 3.2 4.8 1.8 Versicolor
73 6.1 2.8 4 1.3 Versicolor
74 6.3 2.5 4.9 1.5 Versicolor
75 6.1 2.8 4.7 1.2 Versicolor
76 6.4 2.9 4.3 1.3 Versicolor
77 6.6 3 4.4 1.4 Versicolor
78 6.8 2.8 4.8 1.4 Versicolor
79 6.7 3 5 1.7 Versicolor
80 6 2.9 4.5 1.5 Versicolor
81 5.7 2.6 3.5 1 Versicolor
82 5.5 2.4 3.8 1.1 Versicolor
83 5.5 2.4 3.7 1 Versicolor
84 5.8 2.7 3.9 1.2 Versicolor
85 6 2.7 5.1 1.6 Versicolor
86 5.4 3 4.5 1.5 Versicolor
87 6 3.4 4.5 1.6 Versicolor
88 6.7 3.1 4.7 1.5 Versicolor
89 6.3 2.3 4.4 1.3 Versicolor
90 5.6 3 4.1 1.3 Versicolor
91 5.5 2.5 4 1.3 Versicolor
92 5.5 2.6 4.4 1.2 Versicolor
93 6.1 3 4.6 1.4 Versicolor
94 5.8 2.6 4 1.2 Versicolor
95 5 2.3 3.3 1 Versicolor
96 5.6 2.7 4.2 1.3 Versicolor
97 5.7 3 4.2 1.2 Versicolor
98 5.7 2.9 4.2 1.3 Versicolor
99 6.2 2.9 4.3 1.3 Versicolor
100 5.1 2.5 3 1.1 Versicolor
101 5.7 2.8 4.1 1.3 Versicolor
102 6.3 3.3 6 2.5 Virginica
103 5.8 2.7 5.1 1.9 Virginica
104 7.1 3 5.9 2.1 Virginica
105 6.3 2.9 5.6 1.8 Virginica
106 6.5 3 5.8 2.2 Virginica
107 7.6 3 6.6 2.1 Virginica
108 4.9 2.5 4.5 1.7 Virginica
109 7.3 2.9 6.3 1.8 Virginica
110 6.7 2.5 5.8 1.8 Virginica
111 7.2 3.6 6.1 2.5 Virginica
112 6.5 3.2 5.1 2 Virginica
113 6.4 2.7 5.3 1.9 Virginica
114 6.8 3 5.5 2.1 Virginica
115 5.7 2.5 5 2 Virginica
116 5.8 2.8 5.1 2.4 Virginica
117 6.4 3.2 5.3 2.3 Virginica
118 6.5 3 5.5 1.8 Virginica
119 7.7 3.8 6.7 2.2 Virginica
120 7.7 2.6 6.9 2.3 Virginica
121 6 2.2 5 1.5 Virginica
122 6.9 3.2 5.7 2.3 Virginica
123 5.6 2.8 4.9 2 Virginica
124 7.7 2.8 6.7 2 Virginica
125 6.3 2.7 4.9 1.8 Virginica
126 6.7 3.3 5.7 2.1 Virginica
127 7.2 3.2 6 1.8 Virginica
128 6.2 2.8 4.8 1.8 Virginica
129 6.1 3 4.9 1.8 Virginica
130 6.4 2.8 5.6 2.1 Virginica
131 7.2 3 5.8 1.6 Virginica
132 7.4 2.8 6.1 1.9 Virginica
133 7.9 3.8 6.4 2 Virginica
134 6.4 2.8 5.6 2.2 Virginica
135 6.3 2.8 5.1 1.5 Virginica
136 6.1 2.6 5.6 1.4 Virginica
137 7.7 3 6.1 2.3 Virginica
138 6.3 3.4 5.6 2.4 Virginica
139 6.4 3.1 5.5 1.8 Virginica
140 6 3 4.8 1.8 Virginica
141 6.9 3.1 5.4 2.1 Virginica
142 6.7 3.1 5.6 2.4 Virginica
143 6.9 3.1 5.1 2.3 Virginica
144 5.8 2.7 5.1 1.9 Virginica
145 6.8 3.2 5.9 2.3 Virginica
146 6.7 3.3 5.7 2.5 Virginica
147 6.7 3 5.2 2.3 Virginica
148 6.3 2.5 5 1.9 Virginica
149 6.5 3 5.2 2 Virginica
150 6.2 3.4 5.4 2.3 Virginica
151 5.9 3 5.1 1.8 Virginica

BIN
interpreter_demo/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 KiB

401
interpreter_demo/sandbox.py Normal file
View File

@ -0,0 +1,401 @@
import argparse
import asyncio
import json
import logging
import os
import signal
import sys
from asyncio import Queue
from datetime import datetime, timezone
from typing import Annotated, List, Union
import tornado.escape
import tornado.ioloop
import tornado.web
from annotated_types import Gt
from jupyter_client.asynchronous.client import AsyncKernelClient
from jupyter_client.manager import AsyncKernelManager
from pydantic import BaseModel
# Shell Jupyter message types
JupyterMessageTypeExecuteRequest = "execute_request"
JupyterMessageTypeExecuteReply = "execute_reply"
# IOPub Jupyter message types
JupyterMessageTypeStream = "stream"
JupyterMessageTypeDisplayData = "display_data"
JupyterMessageTypeExecuteResult = "execute_result"
JupyterMessageTypeError = "error"
JupyterMessageTypeStatus = "status"
# Supported Jupyter message types (IOPub only)
JupyterSupportedMessageTypes = [
JupyterMessageTypeStream,
JupyterMessageTypeDisplayData,
JupyterMessageTypeExecuteResult,
JupyterMessageTypeError,
JupyterMessageTypeStatus,
]
# Kernel execution states
JupyterExecutionStateBusy = "busy"
JupyterExecutionStateIdle = "idle"
JupyterExecutionStateStarting = "starting"
# Saturn execution event types
ExecutionEventTypeStream = "stream"
ExecutionEventTypeDisplayData = "display_data"
ExecutionEventTypeError = "error"
# Saturn execution statuses
ExecutionStatusOK = "ok"
ExecutionStatusTimeout = "timeout"
class ExecutionEventStream(BaseModel):
stream: str
text: str
class ExecutionEventDisplayData(BaseModel):
variants: dict
class ExecutionEventError(BaseModel):
ename: str
evalue: str
traceback: list[str]
class ExecutionEvent(BaseModel):
type: str
timestamp: str # RFC3339
data: Union[
ExecutionEventStream,
ExecutionEventDisplayData,
ExecutionEventError,
]
class ExecuteRequest(BaseModel):
code: str
timeout_secs: Annotated[int, Gt(0)]
class ExecuteResponse(BaseModel):
status: str
events: List[ExecutionEvent]
class PingResponse(BaseModel):
last_activity: str # RFC3339
class Error(BaseModel):
error: str
def datetime_to_rfc3339(dt: datetime) -> str:
"""Convert a datetime to an RFC3339 formatted string."""
return dt.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%fZ")
def rfc3339_to_datetime(date_string: str) -> datetime:
"""Convert an RFC3339 formatted string to a datetime."""
return datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%fZ").replace(
tzinfo=timezone.utc
)
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
async def async_create_kernel(kernel_name: str):
logging.info(f"Starting kernel for spec '{kernel_name}'")
km = AsyncKernelManager(kernel_name=kernel_name)
await km.start_kernel()
client: AsyncKernelClient = km.client()
client.start_channels()
await client.wait_for_ready()
logging.info("Kernel started")
return km, client
msg_id_to_queue: dict[str, Queue] = {}
async def async_msg_producer(km: AsyncKernelManager, kc: AsyncKernelClient):
try:
while True:
logging.info("Waiting for message...")
msg = await kc.get_iopub_msg()
log_jupyter_kernel_message(msg)
parent_msg_id = msg["parent_header"].get("msg_id")
if parent_msg_id in msg_id_to_queue:
await msg_id_to_queue[parent_msg_id].put(msg)
except Exception as e:
logging.error(f"Error in message producer: {e}")
await async_shutdown(km)
async def async_shutdown(km: AsyncKernelManager):
logging.info("Shutting down kernel...")
await km.shutdown_kernel()
logging.info("Kernel shut down")
sys.exit(0)
class State:
def __init__(self, kernel_client: AsyncKernelClient):
self.last_activity = datetime.now()
self.kernel_client = kernel_client
def reset_last_activity(self):
self.last_activity = datetime.now()
class MainHandler(tornado.web.RequestHandler):
def initialize(self, state: State):
self.state = state
async def get(self):
try:
is_alive = await client.is_alive()
if not is_alive:
raise Exception("kernel is not alive")
self.write(
PingResponse(
last_activity=datetime_to_rfc3339(self.state.last_activity)
).model_dump_json()
)
except Exception as e:
self.set_status(500)
self.write(Error(error=str(e)).model_dump_json())
return
def serializer(o):
if isinstance(o, datetime):
return o.isoformat()
raise TypeError("Type not serializable")
def log_jupyter_kernel_message(msg):
m = json.dumps(msg, default=serializer)
logging.info(f"Jupyter: {m}")
class ExecuteHandler(tornado.web.RequestHandler):
def initialize(self, state: State):
self.state = state
async def post(self):
parent_msg_id = None
res: ExecuteResponse = ExecuteResponse(status=ExecutionStatusOK, events=[])
try:
logging.info(f"Execute request: {self.request.body}")
self.state.reset_last_activity()
req = ExecuteRequest.model_validate_json(self.request.body)
local_queue = Queue()
parent_msg_id = self.state.kernel_client.execute(req.code)
msg_id_to_queue[parent_msg_id] = local_queue
# Use the timeout logic on message processing
try:
await asyncio.wait_for(
self.process_messages(parent_msg_id, local_queue, res),
timeout=req.timeout_secs,
)
except asyncio.TimeoutError:
logging.info(f"Timeout after {req.timeout_secs}s")
res.status = ExecutionStatusTimeout
return self.write(res.model_dump_json())
self.state.reset_last_activity()
self.write(res.model_dump_json())
except Exception as e:
self.set_status(500)
self.write(Error(error=str(e)).model_dump_json())
finally:
# Cleanup after processing all messages
if parent_msg_id is not None and parent_msg_id in msg_id_to_queue:
del msg_id_to_queue[parent_msg_id]
logging.info(f"Execute response: {res.model_dump_json()}")
async def process_messages(self, parent_msg_id, queue, res):
while True:
msg = await queue.get()
if msg["msg_type"] not in JupyterSupportedMessageTypes:
continue
elif msg["msg_type"] == JupyterMessageTypeStatus:
if msg["content"]["execution_state"] == JupyterExecutionStateIdle:
break
elif msg["msg_type"] == JupyterMessageTypeStream:
res.events.append(
ExecutionEvent(
type=ExecutionEventTypeStream,
timestamp=datetime_to_rfc3339(datetime.now()),
data=ExecutionEventStream(
stream=msg["content"]["name"],
text=msg["content"]["text"],
),
)
)
elif msg["msg_type"] == JupyterMessageTypeDisplayData:
res.events.append(
ExecutionEvent(
type=ExecutionEventTypeDisplayData,
timestamp=datetime_to_rfc3339(datetime.now()),
data=ExecutionEventDisplayData(variants=msg["content"]["data"]),
)
)
elif msg["msg_type"] == JupyterMessageTypeError:
res.events.append(
ExecutionEvent(
type=ExecutionEventTypeError,
timestamp=datetime_to_rfc3339(datetime.now()),
data=ExecutionEventError(
ename=msg["content"]["ename"],
evalue=msg["content"]["evalue"],
traceback=msg["content"]["traceback"],
),
)
)
elif msg["msg_type"] == JupyterMessageTypeExecuteResult:
res.events.append(
ExecutionEvent(
type=ExecutionEventTypeDisplayData,
timestamp=datetime_to_rfc3339(datetime.now()),
data=ExecutionEventDisplayData(variants=msg["content"]["data"]),
)
)
@tornado.web.stream_request_body
class FileUploadHandler(tornado.web.RequestHandler):
def initialize(self, state: State):
self.state = state
self.file_obj = None
async def prepare(self):
if self.request.method != "POST":
self.set_status(404)
self.finish()
return
path = self.path_args[0]
full_path = os.path.join("/", path)
os.makedirs(os.path.dirname(full_path), exist_ok=True)
self.file_obj = open(full_path, "wb")
content_length = int(self.request.headers.get("Content-Length", 0))
logging.info(f"File upload: '{path}' (Content-Length: {content_length})")
def data_received(self, chunk):
if self.file_obj:
self.file_obj.write(chunk)
async def post(self, path):
self.state.reset_last_activity()
if self.file_obj:
self.file_obj.close()
self.set_status(201)
class FileDownloadHandler(tornado.web.RequestHandler):
def initialize(self, state: State):
self.state = state
async def get(self, path):
self.state.reset_last_activity()
full_path = os.path.join("/", path)
if not os.path.exists(full_path):
self.set_status(404)
self.write(Error(error="file not found").model_dump_json())
return
content_length = os.path.getsize(full_path)
logging.info(f"File download: '{path}' (Content-Length: {content_length})")
# Set appropriate headers for file download
self.set_header("Content-Length", content_length)
self.set_header("Content-Type", "application/octet-stream")
self.set_header(
"Content-Disposition",
f"attachment; filename*=UTF-8''{tornado.escape.url_escape(os.path.basename(full_path))}",
)
# Stream the file to the client
with open(full_path, "rb") as f:
while True:
chunk = f.read(64 * 1024)
if not chunk:
break
try:
self.write(chunk)
await self.flush()
except tornado.iostream.StreamClosedError:
return
def shutdown(ioloop: tornado.ioloop.IOLoop, km):
logging.info("Shutting down server...")
ioloop.add_callback_from_signal(lambda: async_shutdown(km))
if __name__ == "__main__":
p = argparse.ArgumentParser()
p.add_argument("--port", type=int, default=80)
p.add_argument("--kernel-name", type=str, default="python3")
args = p.parse_args()
km, client = asyncio.run(async_create_kernel(args.kernel_name))
state = State(client)
application = tornado.web.Application(
[
(r"/", MainHandler, {"state": state}),
(r"/execute", ExecuteHandler, {"state": state}),
(r"/files/upload/-/(.*)", FileUploadHandler, {"state": state}),
(r"/files/download/-/(.*)", FileDownloadHandler, {"state": state}),
]
)
application.listen(args.port)
logging.info(f"Server started at http://localhost:{args.port}")
ioloop = tornado.ioloop.IOLoop.current()
signal.signal(signal.SIGINT, lambda sig, frame: shutdown(ioloop, km))
signal.signal(signal.SIGTERM, lambda sig, frame: shutdown(ioloop, km))
ioloop.add_callback(async_msg_producer, km, client)
tornado.ioloop.IOLoop.current().start()

View File

@ -0,0 +1,160 @@
import os
import shutil
import tempfile
import unittest
import requests
from sandbox import (
Error,
ExecuteResponse,
ExecutionEventTypeDisplayData,
ExecutionEventTypeError,
ExecutionEventTypeStream,
ExecutionStatusOK,
ExecutionStatusTimeout,
)
# We'll create a temporary directory for the tests to avoid any side effects.
temp_dir = tempfile.mkdtemp()
BASE_URL = "http://localhost:8888/"
def url(path: str) -> str:
return BASE_URL + path
class TestExecuteHandler(unittest.TestCase):
def must_bind_with_execute_response(self, r: requests.Response) -> ExecuteResponse:
self.assertEqual(r.status_code, 200)
return ExecuteResponse.model_validate_json(r.content)
def must_bind_with_error(self, r: requests.Response) -> Error:
return Error.model_validate_json(r.content)
def test_execute_hello(self):
r = requests.post(
url("execute"), json={"code": "print('hello')", "timeout_secs": 10}
)
res = self.must_bind_with_execute_response(r)
self.assertEqual(len(res.events), 1)
self.assertEqual(res.events[0].type, ExecutionEventTypeStream)
self.assertEqual(res.events[0].data.stream, "stdout") # type: ignore
self.assertEqual(res.events[0].data.text, "hello\n") # type: ignore
def test_execute_timeout(self):
r = requests.post(
url("execute"),
json={"code": "import time\ntime.sleep(5)", "timeout_secs": 1},
)
res = self.must_bind_with_execute_response(r)
self.assertEqual(len(res.events), 0)
self.assertEqual(res.status, ExecutionStatusTimeout)
def test_execute_syntax_error(self):
r = requests.post(
url("execute"), json={"code": "print('hello'", "timeout_secs": 10}
)
err = self.must_bind_with_execute_response(r)
self.assertEqual(err.status, ExecutionStatusOK)
self.assertEqual(len(err.events), 1)
self.assertEqual(err.events[0].type, ExecutionEventTypeError)
self.assertEqual(err.events[0].data.ename, "SyntaxError") # type: ignore
self.assertIsNotNone(err.events[0].data.evalue) # type: ignore
self.assertGreater(len(err.events[0].data.traceback), 0) # type: ignore
def test_execute_invalid_timeout(self):
r = requests.post(
url("execute"),
json={"code": "print('hello')", "timeout_secs": -1},
)
self.must_bind_with_error(r)
def test_execute_display_data(self):
code = """import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()"""
r = requests.post(url("execute"), json={"code": code, "timeout_secs": 10})
res = self.must_bind_with_execute_response(r)
self.assertEqual(res.status, ExecutionStatusOK)
self.assertEqual(len(res.events), 1)
self.assertEqual(res.events[0].type, ExecutionEventTypeDisplayData)
self.assertIsNotNone(res.events[0].data.variants["image/png"]) # type: ignore
self.assertIsNotNone(res.events[0].data.variants["text/plain"]) # type: ignore
def test_execute_pil_image(self):
code = """from PIL import Image
img = Image.new('RGB', (60, 30), color = 'red')
# Override the show method of the Image class
def new_show(self, *args, **kwargs):
display(self)
Image.Image.show = new_show
img.show()"""
r = requests.post(url("execute"), json={"code": code, "timeout_secs": 10})
res = self.must_bind_with_execute_response(r)
self.assertEqual(res.status, ExecutionStatusOK)
self.assertEqual(len(res.events), 1)
self.assertEqual(res.events[0].type, ExecutionEventTypeDisplayData)
self.assertIsNotNone(res.events[0].data.variants["image/png"]) # type: ignore
self.assertIsNotNone(res.events[0].data.variants["text/plain"]) # type: ignore
class FileUploadHandlerTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.temp_dir = tempfile.mkdtemp()
cls.BASE_URL = f"http://localhost:8888/files/upload/-{cls.temp_dir}/"
def test_upload_file(self):
file_path = os.path.join(self.temp_dir, "test.txt")
large_binary_file = os.urandom(1024 * 1024 * 10) # 10 MB
r = requests.post(self.BASE_URL + "test.txt", data=large_binary_file)
self.assertEqual(r.status_code, 201)
self.assertTrue(os.path.exists(file_path))
with open(file_path, "rb") as f:
self.assertEqual(f.read(), large_binary_file)
def test_upload_existing_file(self):
file_path = os.path.join(self.temp_dir, "existing.txt")
with open(file_path, "wb") as f:
f.write(b"exists")
with open(file_path, "rb") as f:
r = requests.post(self.BASE_URL + "existing.txt", data=f.read())
self.assertEqual(r.status_code, 409)
error = Error.model_validate_json(r.content)
self.assertEqual(error.error, "file already exists")
def test_directory_creation(self):
file_path = os.path.join(self.temp_dir, "newdir", "test.txt")
os.makedirs(os.path.dirname(file_path), exist_ok=True)
r = requests.post(self.BASE_URL + "newdir/test.txt", data=b"test content")
self.assertEqual(r.status_code, 201)
self.assertTrue(os.path.exists(file_path))
with open(file_path, "rb") as f:
self.assertEqual(f.read(), b"test content")
@classmethod
def tearDownClass(cls):
# Clean up the temp_dir after all tests
if os.path.exists(cls.temp_dir):
shutil.rmtree(cls.temp_dir)
if __name__ == "__main__":
unittest.main()

40
langchain_demo/README.md Normal file
View File

@ -0,0 +1,40 @@
![](../resources/logo.jpeg)
[English](README.md) | [中文](README_zh.md)
## RAG Functionality
CodeGeeX4 supports RAG functionality and is compatible with the Langchain framework to achieve project-level retrieval Q&A.
## Tutorial
### 1. Install Dependencies
Navigate to the `langchain_demo` directory and install the required packages.
```bash
cd langchain_demo
pip install -r requirements.txt
```
### 2. Configure Embedding API Key
This project uses the Embedding API from the Zhipu Open Platform for vectorization. Please register and obtain an API Key first.
Then, configure the API Key in `models/embedding.py`.
For more details, refer to https://open.bigmodel.cn/dev/api#text_embedding.
### 3. Generate Vector Data
```bash
python vectorize.py --workspace . --output_path vectors
>>> File vectorization completed, saved to vectors
```
### 4. Run the Q&A Script
```bash
python chat.py --vector_path vectors
>>> Running on local URL: http://127.0.0.1:8080
```
## Demo
![](resources/demo.png)

View File

@ -0,0 +1,44 @@
![](../resources/logo.jpeg)
[English](README.md) | [中文](README_zh.md)
## RAG功能
CodeGeeX4支持RAG检索增强并兼容Langchain框架实现项目级检索问答。
## 使用教程
### 1. 安装依赖项
```bash
cd langchain_demo
pip install -r requirements.txt
```
### 2. 配置Embedding API Key
本项目使用智谱开放平台的Embedding API实现向量化功能请先注册并获取API Key。
并在`models/embedding.py`中配置API Key。
详情可参考 https://open.bigmodel.cn/dev/api#text_embedding
### 3. 生成向量数据
```bash
python vectorize.py --workspace . --output_path vectors
>>> 文件向量化完成,已保存至vectors
```
### 4. 运行问答脚本
```bash
python chat.py --vector_path vectors
>>> Running on local URL: http://127.0.0.1:8080
```
## Demo
![](resources/demo_zh.png)

54
langchain_demo/chat.py Normal file
View File

@ -0,0 +1,54 @@
"""
References: https://python.langchain.com/v0.2/docs/tutorials/rag/
"""
import argparse
import gradio as gr
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from models.codegeex import CodegeexChatModel
from utils.prompts import CUSTOM_RAG_PROMPT
from utils.vector import load_vector_store
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument('--vector_path', type=str, help="path to load the vectors", default='vectors')
parser.add_argument('--model_name_or_path', type=str, default='THUDM/codegeex4-all-9b')
parser.add_argument('--device', type=str, help="cpu or cuda", default="cpu")
parser.add_argument('--temperature', type=float, help="model's temperature", default=0.2)
return parser.parse_args()
def format_docs(docs):
return "\n\n".join(
[f"[[citation:{i + 1}]]\n```markdown\n{doc.page_content}\n```" for i, doc in enumerate(docs)]
)
def chat(query, history):
retrieve_chain = ({"context": retriever | format_docs, "question": RunnablePassthrough()} | CUSTOM_RAG_PROMPT)
retrieve_output = retrieve_chain.invoke(query)
ans = retrieve_output.text
yield ans
ans += "模型回复".center(150, '-') + '\n'
yield ans
parse_chain = (llm | StrOutputParser())
ans += parse_chain.invoke(retrieve_output)
yield ans
if __name__ == '__main__':
args = parse_arguments()
llm = CodegeexChatModel(args)
try:
retriever = load_vector_store(args.vector_path).as_retriever()
except Exception as e:
print(f"Fail to load vectorscaused by {e}")
exit()
demo = gr.ChatInterface(chat).queue()
demo.launch(server_name="127.0.0.1", server_port=8080)

View File

@ -0,0 +1,57 @@
from typing import Iterator
import torch
from langchain_core.language_models.chat_models import BaseChatModel
from langchain_core.messages import BaseMessage, AIMessageChunk
from langchain_core.outputs import ChatGenerationChunk, ChatResult, ChatGeneration
from pydantic import Field
from transformers import AutoModel, AutoTokenizer
from utils.prompts import SYS_PROMPT
class CodegeexChatModel(BaseChatModel):
device: str = Field(description="device to load the model")
tokenizer = Field(description="model's tokenizer")
model = Field(description="Codegeex model")
temperature: float = Field(description="temperature to use for the model.")
def __init__(self, args):
super().__init__()
self.device = args.device
self.tokenizer = AutoTokenizer.from_pretrained(args.model_name_or_path, trust_remote_code=True)
self.model = AutoModel.from_pretrained(
args.model_name_or_path,
trust_remote_code=True
).to(args.device).eval()
self.temperature = args.temperature
print("Model has been initialized.")
def _llm_type(self) -> str:
return "codegeex"
@torch.inference_mode()
def _generate(self, messages, **kwargs):
try:
response, _ = self.model.chat(
self.tokenizer,
query=messages[0].content,
history=[{"role": "system", "content": SYS_PROMPT}],
max_new_tokens=1024,
temperature=self.temperature
)
return ChatResult(generations=[ChatGeneration(message=BaseMessage(content=response, type='ai'))])
except Exception as e:
return ChatResult(generations=[ChatGeneration(message=BaseMessage(content=repr(e), type='ai'))])
def _stream(self, messages: list[BaseMessage], **kwargs) -> Iterator[ChatGenerationChunk]:
try:
for response, _ in self.model.stream_chat(
self.tokenizer,
query=messages[0].content,
history=[{"role": "system", "content": SYS_PROMPT}],
max_new_tokens=1024,
temperature=self.temperature
):
yield ChatGenerationChunk(message=AIMessageChunk(content=response))
except Exception as e:
yield ChatGenerationChunk(message=AIMessageChunk(content=f"Fail to generate, cause by {e}"))

View File

@ -0,0 +1,26 @@
import os
from langchain.schema.embeddings import Embeddings
from zhipuai import ZhipuAI
class GLMEmbeddings(Embeddings):
def __init__(self):
self.client = ZhipuAI(api_key=os.getenv("Zhipu_API_KEY"))
self.embedding_size = 1024
def embed_query(self, text: str) -> list[float]:
return self.embed_documents([text])[0]
def embed_documents(self, texts: list[str]) -> list[list[float]]:
return self._get_len_safe_embeddings(texts)
def _get_len_safe_embeddings(self, texts: list[str]) -> list[list[float]]:
try:
# 获取embedding响应
response = self.client.embeddings.create(model="embedding-2", input=texts)
data = [item.embedding for item in response.data]
return data
except Exception as e:
print(f"Fail to get embeddings, caused by {e}")
return []

View File

@ -0,0 +1,12 @@
accelerate==0.31.0
faiss-cpu==1.8
gradio==4.26.0
langchain==0.2.3
langchain-community==0.2.4
regex==2024.5.15
requests==2.31.0
tiktoken==0.7.0
torch==2.3.1
tqdm==4.66.4
transformers==4.39.0
zhipuai~=2.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 KiB

View File

@ -0,0 +1,63 @@
import os
from langchain.text_splitter import (
Language,
RecursiveCharacterTextSplitter as TextSplitter,
)
from langchain_community.document_loaders import TextLoader
Languages = {
'c': Language.CPP,
'cpp': Language.CPP,
'go': Language.GO,
'java': Language.JAVA,
'js': Language.JS,
'md': Language.MARKDOWN,
'py': Language.PYTHON,
'ts': Language.TS,
}
def traverse(repo_path: str) -> list[str]:
"""
Traverse the directory, fetch all files
- skip hidden directories
- only keep the supported files
:param repo_path: path to this repo
"""
def helper(root):
for entry in os.scandir(root):
if entry.name.startswith('.'):
continue
if entry.is_file():
ext = entry.name.split('.')[-1].lower()
if ext not in Languages.keys():
continue
file_paths.append(entry.path)
elif entry.is_dir():
helper(entry.path)
file_paths = []
helper(repo_path)
return sorted(file_paths)
def split_into_chunks(file_path, chunk_size, overlap_size) -> list[str]:
"""
Split file into chunks
:param file_path: path to the file
:param chunk_size: size for each chunk
:param overlap_size: overlap size betweeen 2 chunks
"""
ext = file_path.split('.')[-1].lower()
lang = Languages.get(ext, None)
if not lang:
return []
try:
loader = TextLoader(file_path, encoding='utf-8', autodetect_encoding=True)
splitter = TextSplitter.from_language(lang, chunk_size=chunk_size, chunk_overlap=overlap_size)
return loader.load_and_split(splitter)
except Exception as e:
print(f'`{file_path}`切分失败: {e}')
return []

View File

@ -0,0 +1,22 @@
from langchain_core.prompts import PromptTemplate
SYS_PROMPT = """
你将接收到一个用户提出的问题并请撰写清晰简洁且准确的答案
# Note
- 您将获得与问题相关的多个上下文片段每个上下文都以引用编号开头例如[[citation:x]]其中x是一个数字如果适用请使用上下文并在每个句子的末尾引用上下文
- 您的答案必须是正确的准确的并且以专家的身份使用无偏见和专业的语调来撰写
- 请你的回答限制在2千字以内不要提供与问题无关的信息也不要重复
- 请以引用编号的格式[[citation:x]]来引用上下文如果一个句子来自多个上下文请列出所有适用的引用例如[[citation:3]][[citation:5]]
- 若所有上下文均不相关请以自己的理解回答用户提出的问题此时回答中可以不带引用编号
- 除了代码和特定的名称和引用外您的答案必须使用与问题相同的语言来撰写
""".lstrip()
template = """
[引用]
{context}
{question}
""".lstrip()
CUSTOM_RAG_PROMPT = PromptTemplate.from_template(template)

View File

@ -0,0 +1,42 @@
import os
from langchain_community.docstore import InMemoryDocstore
from langchain_community.vectorstores.faiss import FAISS, dependable_faiss_import
from models.embedding import GLMEmbeddings
from tqdm import tqdm
from utils.data import split_into_chunks
embed_model = GLMEmbeddings()
def vectorize(files: list[str], args):
# split file into chunks
chunks = []
for file in tqdm(files, desc="文件切分"):
chunks.extend(split_into_chunks(file, args.chunk_size, args.overlap_size))
# initialize the vector store
vector_store = FAISS(
embedding_function=embed_model,
index=dependable_faiss_import().IndexFlatL2(embed_model.embedding_size),
docstore=InMemoryDocstore(),
index_to_docstore_id={},
)
# translate to vectors
batch_size = args.batch_size
for i in tqdm(range(0, len(chunks), batch_size), desc="向量化"):
try:
vector_store.add_documents(chunks[i:i + batch_size])
except Exception as e:
print(f"文件向量化失败,{e}")
# save embedded vectors
output_path = args.output_path
os.makedirs(output_path, exist_ok=True)
vector_store.save_local(output_path)
print(f"文件向量化完成,已保存至{output_path}")
def load_vector_store(vector_path: str):
return FAISS.load_local(vector_path, embed_model, allow_dangerous_deserialization=True)

View File

@ -0,0 +1,24 @@
"""
Vectorize your local project
"""
import argparse
from utils.data import traverse
from utils.vector import vectorize
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument('--workspace', type=str, help="directory of the workspace to be vectorized", default='.')
parser.add_argument('--chunk_size', type=int, help="chunk size when splitting", default=512)
parser.add_argument('--overlap_size', type=int, help="chunk overlap when splitting", default=32)
parser.add_argument('--batch_size', type=int, help="embedding batch size", default=16)
parser.add_argument('--output_path', type=str, help="path to save the vectors", default='vectors')
return parser.parse_args()
if __name__ == '__main__':
args = parse_arguments()
files = traverse(args.workspace)
vectorize(files, args)

43
llamaindex_demo/README.md Normal file
View File

@ -0,0 +1,43 @@
![](../resources/logo.jpeg)
[English](README.md) | [中文](README_zh.md)
## RAG Functionality
CodeGeeX4 supports RAG retrieval enhancement and is compatible with the LlamaIndex framework to achieving project-level retrieval Q&A.
## Usage Tutorial
### 1. Install Dependencies
```bash
cd llamaindex_demo
pip install -r requirements.txt
```
Note: This project uses tree-sitter-language, which has compatibility issues with Python 3.10, so please use Python 3.8 or Python 3.9 to run
this project.
### 2. Configure Embedding API Key
This project uses the Zhipu Open Platform's Embedding API to implement vectorization. Please register and obtain an API Key first.
Then configure the API Key in `models/embedding.py`.
For details, refer to https://open.bigmodel.cn/dev/api#text_embedding
### 3. Generate Vector Data
```bash
python vectorize.py --workspace . --output_path vectors
>>> File vectorization completed, saved to vectors
```
### 4. Run the Q&A Script
```bash
python chat.py --vector_path vectors
>>> Running on local URL: http://127.0.0.1:8080
```
## Demo
![](resources/demo.png)

View File

@ -0,0 +1,46 @@
![](../resources/logo.jpeg)
[English](README.md) | [中文](README_zh.md)
## RAG功能
CodeGeeX4支持RAG检索增强并兼容LlamaIndex框架实现项目级检索问答。
## 使用教程
### 1. 安装依赖项
```bash
cd llamaindex_demo
pip install -r requirements.txt
```
此项目使用到tree-sitter-language其与python3.10兼容的有问题因此请使用python3.8或python3.9运行该项目。
### 2. 配置Embedding API Key
本项目使用智谱开放平台的Embedding API实现向量化功能请先注册并获取API Key。
并在`models/embedding.py`中配置API Key。
详情可参考 https://open.bigmodel.cn/dev/api#text_embedding
### 3. 生成向量数据
```bash
python vectorize.py --workspace . --output_path vectors
>>> 文件向量化完成,已保存至vectors
```
### 4. 运行问答脚本
```bash
python chat.py --vector_path vectors
>>> Running on local URL: http://127.0.0.1:8080
```
## Demo
![](resources/demo_zh.png)

51
llamaindex_demo/chat.py Normal file
View File

@ -0,0 +1,51 @@
"""
References: https://docs.llamaindex.ai/en/stable/use_cases/q_and_a/
"""
import argparse
import gradio as gr
from llama_index.core import Settings
from models.embedding import GLMEmbeddings
from models.synthesizer import CodegeexSynthesizer
from utils.vector import load_vectors
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument('--vector_path', type=str, help="path to store the vectors", default='vectors')
parser.add_argument('--model_name_or_path', type=str, default='THUDM/codegeex4-all-9b')
parser.add_argument('--device', type=str, help="cpu or cuda", default="cpu")
parser.add_argument('--temperature', type=float, help="model's temperature", default=0.2)
return parser.parse_args()
def chat(query, history):
resp = query_engine.query(query)
ans = "相关文档".center(150, '-') + '\n'
yield ans
for i, node in enumerate(resp.source_nodes):
file_name = node.metadata['filename']
ext = node.metadata['extension']
text = node.text
ans += f"File{i + 1}: {file_name}\n```{ext}\n{text}\n```\n"
yield ans
ans += "模型回复".center(150, '-') + '\n'
ans += resp.response
yield ans
if __name__ == '__main__':
args = parse_arguments()
Settings.embed_model = GLMEmbeddings()
try:
query_engine = load_vectors(args.vector_path).as_query_engine(
response_synthesizer=CodegeexSynthesizer(args)
)
except Exception as e:
print(f"Fail to load vectors, caused by {e}")
exit()
demo = gr.ChatInterface(chat).queue()
demo.launch(server_name="127.0.0.1", server_port=8080)

View File

@ -0,0 +1,108 @@
from llama_index.core.base.llms.types import (
ChatMessage,
ChatResponse,
ChatResponseGen,
CompletionResponse,
CompletionResponseGen,
LLMMetadata,
)
from llama_index.core.llms import LLM
from pydantic import Field
from transformers import AutoTokenizer, AutoModel
from utils.prompts import SYS_PROMPT
class CodegeexChatModel(LLM):
device: str = Field(description="device to load the model")
tokenizer = Field(description="model's tokenizer")
model = Field(description="Codegeex model")
temperature: float = Field(description="temperature to use for the model.")
def __init__(self, args):
super().__init__()
self.device = args.device
self.tokenizer = AutoTokenizer.from_pretrained(args.model_name_or_path, trust_remote_code=True)
self.model = AutoModel.from_pretrained(args.model_name_or_path, trust_remote_code=True).to(args.device).eval()
self.temperature = args.temperature
print("Model has been initialized.")
@classmethod
def class_name(cls) -> str:
return "codegeex"
@property
def metadata(self) -> LLMMetadata:
return LLMMetadata(
context_window=7168,
num_output=1024,
is_chat_model=True,
model_name="codegeex",
)
def chat(self, messages: list[ChatMessage], **kwargs) -> ChatResponse:
try:
response, _ = self.model.chat(
self.tokenizer,
query=messages[0].content,
history=[{"role": "system", "content": SYS_PROMPT}],
max_new_tokens=1024,
temperature=self.temperature
)
return ChatResponse(message=ChatMessage(role="assistant", content=response))
except Exception as e:
return ChatResponse(message=ChatMessage(role="assistant", content=e))
def stream_chat(self, messages: list[ChatMessage], **kwargs) -> ChatResponseGen:
try:
for response, _ in self.model.stream_chat(
self.tokenizer,
query=messages[0].content,
history=[{"role": "system", "content": SYS_PROMPT}],
max_new_tokens=1024,
temperature=self.temperature
):
yield ChatResponse(message=ChatMessage(role="assistant", content=response))
except Exception as e:
yield ChatResponse(message=ChatMessage(role="assistant", content=e))
def complete(self, prompt: str, formatted: bool = False, **kwargs) -> CompletionResponse:
try:
response, _ = self.model.chat(
self.tokenizer,
query=prompt,
history=[{"role": "system", "content": "你是一个智能编程助手"}],
max_new_tokens=1024,
temperature=self.temperature
)
return CompletionResponse(text=response)
except Exception as e:
return CompletionResponse(text=e)
def stream_complete(self, prompt: str, formatted: bool = False, **kwargs) -> CompletionResponseGen:
try:
for response, _ in self.model.stream_chat(
self.tokenizer,
query=prompt,
history=[{"role": "system", "content": "你是一个智能编程助手"}],
max_new_tokens=1024,
temperature=self.temperature
):
yield CompletionResponse(text=response)
except Exception as e:
yield CompletionResponse(text=e)
async def achat(self, messages: list[ChatMessage], **kwargs):
return await self.chat(messages, **kwargs)
async def astream_chat(self, messages: list[ChatMessage], **kwargs):
async for resp in self.stream_chat(messages, **kwargs):
yield resp
async def acomplete(self, prompt: str, formatted: bool = False, **kwargs):
return await self.complete(prompt, formatted, **kwargs)
async def astream_complete(self, prompt: str, formatted: bool = False, **kwargs):
async for resp in self.stream_complete(prompt, formatted, **kwargs):
yield resp

View File

@ -0,0 +1,37 @@
import os
from llama_index.core.base.embeddings.base import BaseEmbedding
from pydantic import Field
from zhipuai import ZhipuAI
class GLMEmbeddings(BaseEmbedding):
client = Field(description="embedding model client")
embedding_size: float = Field(description="embedding size")
def __init__(self):
super().__init__(model_name='GLM', embed_batch_size=64)
self.client = ZhipuAI(api_key=os.getenv("Zhipu_API_KEY"))
self.embedding_size = 1024
def _get_query_embedding(self, query: str) -> list[float]:
return self._get_text_embeddings([query])[0]
def _get_text_embedding(self, text: str) -> list[float]:
return self._get_text_embeddings([text])[0]
def _get_text_embeddings(self, texts: list[str]) -> list[list[float]]:
return self._get_len_safe_embeddings(texts)
async def _aget_query_embedding(self, query: str) -> list[float]:
return self._get_query_embedding(query)
def _get_len_safe_embeddings(self, texts: list[str]) -> list[list[float]]:
try:
# 获取embedding响应
response = self.client.embeddings.create(model="embedding-2", input=texts)
data = [item.embedding for item in response.data]
return data
except Exception as e:
print(f"Fail to get embeddings, caused by {e}")
return []

View File

@ -0,0 +1,39 @@
from llama_index.core.response_synthesizers import BaseSynthesizer
from models.codegeex import CodegeexChatModel
from utils.prompts import CUSTOM_PROMPT_TEMPLATE
class CodegeexSynthesizer(BaseSynthesizer):
"""Response builder class."""
def __init__(self, args) -> None:
super().__init__(llm=CodegeexChatModel(args))
self.prompt_template = CUSTOM_PROMPT_TEMPLATE
def get_response(self, query_str: str, text_chunks: list[str], **kwargs) -> str:
context = self.build_context(text_chunks)
return self._llm.predict(self.prompt_template, query=query_str, context=context)
async def aget_response(self, query_str: str, text_chunks: list[str], **kwargs) -> str:
context = self.build_context(text_chunks)
return await self._llm.apredict(self.prompt_template, query=query_str, context=context)
def _get_prompts(self):
"""Get prompts."""
return {"text_qa_template": self.prompt_template}
def _update_prompts(self, prompts) -> None:
"""Update prompts."""
if "text_qa_template" in prompts:
self.prompt_template = prompts["text_qa_template"]
@staticmethod
def build_context(text_chunks):
"""
merge contexts
:param text_chunks: recalled texts
"""
return "\n\n".join(
[f"[[citation:{i + 1}]]\n```markdown\n{chunk}\n```" for i, chunk in enumerate(text_chunks)]
)

View File

@ -0,0 +1,12 @@
accelerate==0.31.0
faiss-cpu==1.8
gradio==4.26.0
llama-index==0.10.43
regex==2024.5.15
tiktoken==0.7.0
torch==2.3.1
tree-sitter<0.22.0
tree-sitter-languages==1.10.2
tqdm==4.66.4
transformers==4.39.0
zhipuai~=2.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 959 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 KiB

View File

@ -0,0 +1,68 @@
import os
from pathlib import Path
from llama_index.core.node_parser import CodeSplitter
from llama_index.core.schema import BaseNode
from llama_index.readers.file import FlatReader
Languages = {
'c': "c",
'cpp': "cpp",
'go': "go",
'java': "java",
'js': "javascript",
'md': "markdown",
'py': "python",
'ts': "typescript",
}
def traverse(repo_path: str) -> list[str]:
"""
Traverse the directory, fetch all files
- skip hidden directories
- only keep the supported files
:param repo_path: path to this repo
"""
def helper(root):
for entry in os.scandir(root):
if entry.name.startswith('.'):
continue
if entry.is_file():
ext = entry.name.split('.')[-1].lower()
if ext not in Languages.keys():
continue
file_paths.append(entry.path)
elif entry.is_dir():
helper(entry.path)
file_paths = []
helper(repo_path)
return sorted(file_paths)
def split_into_chunks(file_path, lines_per_chunk, lines_overlap, max_chars) -> list[BaseNode]:
"""
Split file into chunks
:param file_path: path to the file
:param lines_per_chunk: lines for each chunk
:param lines_overlap: overlap lines between 2 chunks
:param max_chars: max characters for each chunk
"""
ext = file_path.split('.')[-1].lower()
lang = Languages.get(ext, None)
if not lang:
return []
try:
documents = FlatReader().load_data(Path(file_path))
splitter = CodeSplitter(
language=lang,
chunk_lines=lines_per_chunk,
chunk_lines_overlap=lines_overlap,
max_chars=max_chars,
)
return splitter.get_nodes_from_documents(documents)
except Exception as e:
print(f'`{file_path}`切分失败: {e}')
return []

View File

@ -0,0 +1,22 @@
from llama_index.core import PromptTemplate
SYS_PROMPT = """
你将接收到一个用户提出的问题并请撰写清晰简洁且准确的答案
# Note
- 您将获得与问题相关的多个上下文片段每个上下文都以引用编号开头例如[[citation:x]]其中x是一个数字如果适用请使用上下文并在每个句子的末尾引用上下文
- 您的答案必须是正确的准确的并且以专家的身份使用无偏见和专业的语调来撰写
- 请你的回答限制在2千字以内不要提供与问题无关的信息也不要重复
- 请以引用编号的格式[[citation:x]]来引用上下文如果一个句子来自多个上下文请列出所有适用的引用例如[[citation:3]][[citation:5]]
- 若所有上下文均不相关请以自己的理解回答用户提出的问题此时回答中可以不带引用编号
- 除了代码和特定的名称和引用外您的答案必须使用与问题相同的语言来撰写
""".lstrip()
template = """
[引用]
{context}
{query}
""".lstrip()
CUSTOM_PROMPT_TEMPLATE = PromptTemplate(template, prompt_type='text_qa')

View File

@ -0,0 +1,36 @@
import os
import faiss
from llama_index.core import StorageContext, VectorStoreIndex, load_index_from_storage
from llama_index.legacy.vector_stores import FaissVectorStore
from models.embedding import GLMEmbeddings
from tqdm import tqdm
from utils.data import split_into_chunks
embed_model = GLMEmbeddings()
def save_vectors(files: list[str], args):
# split file into chunks
nodes = []
for file in tqdm(files, desc="文件切分"):
nodes.extend(split_into_chunks(file, args.lines_per_chunk, args.lines_overlap, args.max_chars))
# initialize vector store
vector_store = FaissVectorStore(faiss_index=faiss.IndexFlatL2(embed_model.embedding_size))
storage_context = StorageContext.from_defaults(vector_store=vector_store)
# translate to vectors
index = VectorStoreIndex(nodes=nodes, storage_context=storage_context, embed_model=embed_model)
# save embedded vectors
output_path = args.output_path
os.makedirs(output_path, exist_ok=True)
index.storage_context.persist(persist_dir=output_path)
print(f"文件向量化完成,已保存至{output_path}")
def load_vectors(vector_path: str):
vector_store = FaissVectorStore.from_persist_dir(vector_path)
storage_context = StorageContext.from_defaults(vector_store=vector_store, persist_dir=vector_path)
return load_index_from_storage(storage_context=storage_context)

View File

@ -0,0 +1,20 @@
import argparse
from utils.data import traverse
from utils.vector import save_vectors
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument('--workspace', type=str, help="directory of the workspace to be vectorized", default='.')
parser.add_argument('--lines_per_chunk', type=int, help="chunk lines when splitting", default=40)
parser.add_argument('--lines_overlap', type=int, help="chunk lines overlap when splitting", default=15)
parser.add_argument("--max_chars", type=int, help="maximum number of characters in a chunk", default=1500)
parser.add_argument('--output_path', type=str, help="path to save the vectors", default='vectors')
return parser.parse_args()
if __name__ == '__main__':
args = parse_arguments()
files = traverse(args.workspace)
save_vectors(files, args)

49
metric/README.md Normal file
View File

@ -0,0 +1,49 @@
# The Most Powerful Versatile Code Model Under 10 Billion Parameters
CodeGeeX4-ALL-9B, the open-source version of the latest generation of the CodeGeeX4 series, iterates on the powerful language capabilities of GLM4, significantly enhancing code generation capabilities. Using a single CodeGeeX4-ALL-9B model, it supports comprehensive functionalities such as code completion and generation, code interpreter, online search, tool invocation, repository-level long code Q&A and generation, covering various programming and development scenarios. CodeGeeX4-ALL-9B has achieved highly competitive performance on multiple authoritative code capability evaluation sets, such as NaturalCodeBench and BigCodeBench. It is the most powerful model under 10 billion parameters, even surpassing general models several times its size, achieving the best balance between inference performance and model effectiveness.
## 1. BigCodeBench
BigCodeBench test results show that CodeGeeX4-ALL-9B performs the best at the same size:
![BigCodeBench Test Results](./pics/Bigcodebench.png)
## 2. NaturalCodeBench & HumanEval
NaturalCodeBench test results show that CodeGeeX4-ALL-9B achieves the best results in tasks such as code completion, code interpreter, code Q&A, code translation, and code repair:
![NaturalCodeBench Test Results](./pics/NCB&HUMANEVAL.png)
## 3. Code Needle In A Haystack
CodeGeeX4-ALL-9B's context handling capability has reached 128K, an 8-fold increase compared to the previous generation model!
For code large models under 10B parameters, accurately extracting information from massive amounts of code is a key challenge. CodeGeeX4-ALL-9B's upgraded support for 128K context enables it to process and utilize longer code files, and even information from project code, helping the model to understand complex and detail-rich code more deeply. Based on the longer context, CodeGeeX4-ALL-9B can handle more complex project-level tasks, accurately answering content from different code files and making modifications to the code even when the input length increases significantly.
In the "Needle In A Haystack" (NIAH) evaluation, the CodeGeeX4-ALL-9B model demonstrated its ability to embed and retrieve code within contexts up to 128K, achieving a 100% retrieval accuracy.
![NIAH_PYTHON Evaluation](./pics/NIAH_PYTHON.png)
![NIAH_ALL_FILES Evaluation](./pics/NIAH_ALL.png)
The above figures show the test results in a test set composed entirely of Python code, where an assignment statement such as `zhipu_codemodel = "codegeex"` (Needle) is inserted, and the model is tested on whether it can correctly answer the value of `zhipu_codemodel`. CodeGeeX4-All-9B completed the task 100%.
## 4. Function Call Capabilities
CodeGeeX4-ALL-9B is currently the only code large model that implements Function Call capabilities.
The Berkeley Function Calling Leaderboard is the first test set that can comprehensively evaluate the function calling capabilities of large models. The AST dataset evaluates the model's calling capabilities for Java, JavaScript, and Python programs; the Executable dataset evaluates the model's function calling capabilities for real-world API scenarios.
![Berkeley Function Calling Leaderboard](./pics/FunctionCall.png)
CodeGeeX4-ALL-9B underwent comprehensive testing on the Berkeley Function Calling Leaderboard, including various forms of function calls, different function call scenarios, and function call executability tests, achieving the following results: a call success rate of over 90% in both AST and Exec test sets.
## 5. Cross-File Completion
Cross-File Evaluation is a multilingual benchmark built on diverse real-world repositories in Python, Java, TypeScript, and C#. It uses a static-analysis-based method to strictly require cross-file context for accurate code completion.
| Model | PYTHON EM | PYTHON ES | JAVA EM | JAVA ES | TypeScript EM | TypeScript ES | C# EM | C# ES |
|------------------|------------|------------|----------|----------|----------------|----------------|---------|---------|
| DeepSeekCoder-7B | 29.9 | 62.9 | 39.8 | 74.8 | 39 | 77 | 52.2 | 78.1 |
| StarCoder2-7B | 25.3 | 58 | 31.4 | 67.4 | 33.3 | 73.2 | 43.5 | 69.8 |
| CodeLlama-7B | 23.5 | 53.5 | 33.9 | 68.4 | 11.5 | 71.5 | 50.6 | 75.4 |
| CodeGeeX-9B | 32.3 | 70.3 | 48.6 | 84.4 | 35.3 | 78.0 | 48.0 | 84.8 |

50
metric/README_zh.md Normal file
View File

@ -0,0 +1,50 @@
# CodeGeeX4-ALL-9B
## CodeGeeX4-ALL-9B百亿参数以下性能最强的全能代码模型
CodeGeeX4-ALL-9B作为最新一代CodeGeeX4系列模型的开源版本在GLM4强大语言能力的基础上继续迭代大幅增强代码生成能力。使用CodeGeeX4-ALL-9B单一模型即可支持代码补全和生成、代码解释器、联网搜索、工具调用、仓库级长代码问答及生成等全面功能覆盖了编程开发的各种场景。CodeGeeX4-ALL-9B在多个权威代码能力评测集如NaturalCodeBench、BigCodeBench上都取得了极具竞争力的表现是百亿参数量级以下性能最强的模型甚至超过数倍规模的通用模型在推理性能和模型效果上得到最佳平衡。
### 1. 性能表现评测
BigCodeBench测试结果显示CodeGeeX4-ALL-9B在同等尺寸下效果最好
![BigCodeBench Test Results](./pics/Bigcodebench.png)
NaturalCodeBench测试结果显示CodeGeeX4-ALL-9B在代码补全、代码解释器、代码问答、代码翻译、代码修复等任务上均取得了最佳效果
![NaturalCodeBench测试结果](./pics/NCB&HUMANEVAL.png)
### 2. CodeGeeX4-ALL-9B上下文处理能力
CodeGeeX4-ALL-9B上下文处理能力达到了128K相较于上一代模型增长8倍
对于参数量10B以下的代码大模型从海量的代码中准确提取信息是一个关键性的挑战。CodeGeeX4-ALL-9B升级支持128K上下文使其能够处理和利用更长代码文件、甚至是项目代码中的信息有助于模型更深入理解复杂和细节丰富的代码。基于更长的上下文CodeGeeX4-ALL-9B可以处理更复杂的项目级任务在输入显著变长的情况下依然能准确回答不同代码文件中的内容并对代码作出修改。
在“大海捞针”Needle In A Haystack, NIAH评估中CodeGeeX4-ALL-9B模型展示了其在处理长达128K的上下文中进行代码的嵌入和检索能力实现了100%的检索准确度。
![NIAH_PYTHON评估](./pics/NIAH_PYTHON.png)
![NIAH_ALL_FILES评估](./pics/NIAH_ALL.png)
上图展示的是在一个全部由Python代码组成的测试集中插入一个赋值语句如`zhipu_codemodel = "codegeex"`Needle测试模型是否可以正确回答出`zhipu_codemodel`的值CodeGeeX4-ALL-9B 100%完成任务。
### 3. CodeGeeX4-ALL-9B 支持 Function Call 能力
CodeGeeX4-ALL-9B是目前唯一一个实现Function Call的代码大模型。
Berkeley Function Calling Leaderboard是第一个可全面评估大模型函数调用能力的测试集。其中AST数据集是评估模型对Java、JavaScript、Python程序的调用能力Executable数据集是评估模型对真实场景API的函数调用能力。
![Berkeley Function Calling Leaderboard](./pics/FunctionCall.png)
CodeGeeX4-ALL-9B在Berkeley Function Calling Leaderboard上进行了全面的测试包括各种形式的函数调用、不同的函数调用场景以及函数调用可执行性的测试得到了以下结果在AST和Exec测试集中调用成功率超过90%。
### 4. CodeGeeX4-ALL-9B 跨文件补全
Cross-File Evaluation是一个多语言的基准建立在Python、Java、TypeScript和C#的多样化真实仓库之上。它使用基于静态分析的方法,严格要求跨文件上下文以实现准确的代码补全。
| Model | PYTHON EM | PYTHON ES | JAVA EM | JAVA ES | TypeScript EM | TypeScript ES | C# EM | C# ES |
|------------------|------------|------------|----------|----------|----------------|----------------|---------|---------|
| DeepSeekCoder-7B | 29.9 | 62.9 | 39.8 | 74.8 | 39 | 77 | 52.2 | 78.1 |
| StarCoder2-7B | 25.3 | 58 | 31.4 | 67.4 | 33.3 | 73.2 | 43.5 | 69.8 |
| CodeLlama-7B | 23.5 | 53.5 | 33.9 | 68.4 | 11.5 | 71.5 | 50.6 | 75.4 |
| CodeGeeX-9B | 32.3 | 70.3 | 48.6 | 84.4 | 35.3 | 78.0 | 48.0 | 84.8 |

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
metric/pics/NIAH_ALL.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
metric/pics/NIAH_PYTHON.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
metric/pics/cce.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@ -0,0 +1,118 @@
[project]
# Whether to enable telemetry (default: true). No personal data is collected.
enable_telemetry = false
# List of environment variables to be provided by each user to use the app.
user_env = []
# Duration (in seconds) during which the session is saved when the connection is lost
session_timeout = 3600
# Enable third parties caching (e.g LangChain cache)
cache = false
# Authorized origins
allow_origins = ["*"]
# Follow symlink for asset mount (see https://github.com/Chainlit/chainlit/issues/317)
# follow_symlink = false
[features]
# Process and display HTML in messages. This can be a security risk (see https://stackoverflow.com/questions/19603097/why-is-it-dangerous-to-render-user-generated-html-or-javascript)
unsafe_allow_html = false
# Process and display mathematical expressions. This can clash with "$" characters in messages.
latex = false
# Automatically tag threads with the current chat profile (if a chat profile is used)
auto_tag_thread = true
# Authorize users to spontaneously upload files with messages
[features.spontaneous_file_upload]
enabled = false
accept = ["*/*"]
max_files = 20
max_size_mb = 500
[features.audio]
# Threshold for audio recording
min_decibels = -45
# Delay for the user to start speaking in MS
initial_silence_timeout = 3000
# Delay for the user to continue speaking in MS. If the user stops speaking for this duration, the recording will stop.
silence_timeout = 1500
# Above this duration (MS), the recording will forcefully stop.
max_duration = 15000
# Duration of the audio chunks in MS
chunk_duration = 1000
# Sample rate of the audio
sample_rate = 44100
[UI]
# Name of the assistant.
name = "CodeGeeX4 RepoDome"
# Description of the assistant. This is used for HTML tags.
description = "CodeGeeX4项目级能力展示"
# Large size content are by default collapsed for a cleaner ui
default_collapse_content = true
# Hide the chain of thought details from the user in the UI.
hide_cot = false
# Link to your github repo. This will add a github button in the UI's header.
github = "https://github.com/CodeGeeX"
# Specify a CSS file that can be used to customize the user interface.
# The CSS file can be served from the public directory or via an external link.
# custom_css = "/public/test.css"
# Specify a Javascript file that can be used to customize the user interface.
# The Javascript file can be served from the public directory.
# custom_js = "/public/test.js"
# Specify a custom font url.
# custom_font = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap"
# Specify a custom meta image url.
custom_meta_image_url = "/public/logo_dark.png"
# Specify a custom build directory for the frontend.
# This can be used to customize the frontend code.
# Be careful: If this is a relative path, it should not start with a slash.
# custom_build = "./public/build"
[UI.theme]
default = "dark"
layout = "wide"
#font_family = "Inter, sans-serif"
# Override default MUI light theme. (Check theme.ts)
[UI.theme.light]
#background = "#FAFAFA"
#paper = "#FFFFFF"
[UI.theme.light.primary]
#main = "#F80061"
#dark = "#980039"
#light = "#FFE7EB"
[UI.theme.light.text]
#primary = "#212121"
#secondary = "#616161"
# Override default MUI dark theme. (Check theme.ts)
[UI.theme.dark]
#background = "#FAFAFA"
#paper = "#FFFFFF"
[UI.theme.dark.primary]
#main = "#F80061"
#dark = "#980039"
#light = "#FFE7EB"
[UI.theme.dark.text]
#primary = "#EEEEEE"
#secondary = "#BDBDBD"
[meta]
generated_by = "1.1.305"

View File

@ -0,0 +1,229 @@
{
"components": {
"atoms": {
"buttons": {
"userButton": {
"menu": {
"settings": "Settings",
"settingsKey": "S",
"APIKeys": "API Keys",
"logout": "Logout"
}
}
}
},
"molecules": {
"newChatButton": {
"newChat": "New Chat"
},
"tasklist": {
"TaskList": {
"title": "\ud83d\uddd2\ufe0f Task List",
"loading": "Loading...",
"error": "An error occurred"
}
},
"attachments": {
"cancelUpload": "Cancel upload",
"removeAttachment": "Remove attachment"
},
"newChatDialog": {
"createNewChat": "Create new chat?",
"clearChat": "This will clear the current messages and start a new chat.",
"cancel": "Cancel",
"confirm": "Confirm"
},
"settingsModal": {
"settings": "Settings",
"expandMessages": "Expand Messages",
"hideChainOfThought": "Hide Chain of Thought",
"darkMode": "Dark Mode"
},
"detailsButton": {
"using": "Using",
"used": "Used"
},
"auth": {
"authLogin": {
"title": "Login to access the app.",
"form": {
"email": "Email address",
"password": "Password",
"noAccount": "Don't have an account?",
"alreadyHaveAccount": "Already have an account?",
"signup": "Sign Up",
"signin": "Sign In",
"or": "OR",
"continue": "Continue",
"forgotPassword": "Forgot password?",
"passwordMustContain": "Your password must contain:",
"emailRequired": "email is a required field",
"passwordRequired": "password is a required field"
},
"error": {
"default": "Unable to sign in.",
"signin": "Try signing in with a different account.",
"oauthsignin": "Try signing in with a different account.",
"redirect_uri_mismatch": "The redirect URI is not matching the oauth app configuration.",
"oauthcallbackerror": "Try signing in with a different account.",
"oauthcreateaccount": "Try signing in with a different account.",
"emailcreateaccount": "Try signing in with a different account.",
"callback": "Try signing in with a different account.",
"oauthaccountnotlinked": "To confirm your identity, sign in with the same account you used originally.",
"emailsignin": "The e-mail could not be sent.",
"emailverify": "Please verify your email, a new email has been sent.",
"credentialssignin": "Sign in failed. Check the details you provided are correct.",
"sessionrequired": "Please sign in to access this page."
}
},
"authVerifyEmail": {
"almostThere": "You're almost there! We've sent an email to ",
"verifyEmailLink": "Please click on the link in that email to complete your signup.",
"didNotReceive": "Can't find the email?",
"resendEmail": "Resend email",
"goBack": "Go Back",
"emailSent": "Email sent successfully.",
"verifyEmail": "Verify your email address"
},
"providerButton": {
"continue": "Continue with {{provider}}",
"signup": "Sign up with {{provider}}"
},
"authResetPassword": {
"newPasswordRequired": "New password is a required field",
"passwordsMustMatch": "Passwords must match",
"confirmPasswordRequired": "Confirm password is a required field",
"newPassword": "New password",
"confirmPassword": "Confirm password",
"resetPassword": "Reset Password"
},
"authForgotPassword": {
"email": "Email address",
"emailRequired": "email is a required field",
"emailSent": "Please check the email address {{email}} for instructions to reset your password.",
"enterEmail": "Enter your email address and we will send you instructions to reset your password.",
"resendEmail": "Resend email",
"continue": "Continue",
"goBack": "Go Back"
}
}
},
"organisms": {
"chat": {
"history": {
"index": {
"showHistory": "Show history",
"lastInputs": "Last Inputs",
"noInputs": "Such empty...",
"loading": "Loading..."
}
},
"inputBox": {
"input": {
"placeholder": "Type your message here..."
},
"speechButton": {
"start": "Start recording",
"stop": "Stop recording"
},
"SubmitButton": {
"sendMessage": "Send message",
"stopTask": "Stop Task"
},
"UploadButton": {
"attachFiles": "Attach files"
},
"waterMark": {
"text": "Built with"
}
},
"Messages": {
"index": {
"running": "Running",
"executedSuccessfully": "executed successfully",
"failed": "failed",
"feedbackUpdated": "Feedback updated",
"updating": "Updating"
}
},
"dropScreen": {
"dropYourFilesHere": "Drop your files here"
},
"index": {
"failedToUpload": "Failed to upload",
"cancelledUploadOf": "Cancelled upload of",
"couldNotReachServer": "Could not reach the server",
"continuingChat": "Continuing previous chat"
},
"settings": {
"settingsPanel": "Settings panel",
"reset": "Reset",
"cancel": "Cancel",
"confirm": "Confirm"
}
},
"threadHistory": {
"sidebar": {
"filters": {
"FeedbackSelect": {
"feedbackAll": "Feedback: All",
"feedbackPositive": "Feedback: Positive",
"feedbackNegative": "Feedback: Negative"
},
"SearchBar": {
"search": "Search"
}
},
"DeleteThreadButton": {
"confirmMessage": "This will delete the thread as well as it's messages and elements.",
"cancel": "Cancel",
"confirm": "Confirm",
"deletingChat": "Deleting chat",
"chatDeleted": "Chat deleted"
},
"index": {
"pastChats": "Past Chats"
},
"ThreadList": {
"empty": "Empty...",
"today": "Today",
"yesterday": "Yesterday",
"previous7days": "Previous 7 days",
"previous30days": "Previous 30 days"
},
"TriggerButton": {
"closeSidebar": "Close sidebar",
"openSidebar": "Open sidebar"
}
},
"Thread": {
"backToChat": "Go back to chat",
"chatCreatedOn": "This chat was created on"
}
},
"header": {
"chat": "Chat",
"readme": "Readme"
}
}
},
"hooks": {
"useLLMProviders": {
"failedToFetchProviders": "Failed to fetch providers:"
}
},
"pages": {
"Design": {},
"Env": {
"savedSuccessfully": "Saved successfully",
"requiredApiKeys": "Required API Keys",
"requiredApiKeysInfo": "To use this app, the following API keys are required. The keys are stored on your device's local storage."
},
"Page": {
"notPartOfProject": "You are not part of this project."
},
"ResumeButton": {
"resumeChat": "Resume Chat"
}
}
}

View File

@ -0,0 +1,229 @@
{
"components": {
"atoms": {
"buttons": {
"userButton": {
"menu": {
"settings": "设置",
"settingsKey": "S",
"APIKeys": "API 密钥",
"logout": "登出"
}
}
}
},
"molecules": {
"newChatButton": {
"newChat": "新聊天"
},
"tasklist": {
"TaskList": {
"title": "🗒️ 任务列表",
"loading": "加载中...",
"error": "发生错误"
}
},
"attachments": {
"cancelUpload": "取消上传",
"removeAttachment": "移除附件"
},
"newChatDialog": {
"createNewChat": "创建新聊天?",
"clearChat": "这将清除当前消息并开始新聊天。",
"cancel": "取消",
"confirm": "确认"
},
"settingsModal": {
"settings": "设置",
"expandMessages": "展开消息",
"hideChainOfThought": "隐藏思路",
"darkMode": "深色模式"
},
"detailsButton": {
"using": "正在使用",
"used": "已使用"
},
"auth": {
"authLogin": {
"title": "登录以访问应用程序。",
"form": {
"email": "电子邮件地址",
"password": "密码",
"noAccount": "没有账户?",
"alreadyHaveAccount": "已有账户?",
"signup": "注册",
"signin": "登录",
"or": "或",
"continue": "继续",
"forgotPassword": "忘记密码?",
"passwordMustContain": "您的密码必须包含:",
"emailRequired": "电子邮件是必填字段",
"passwordRequired": "密码是必填字段"
},
"error": {
"default": "无法登录。",
"signin": "尝试使用其他账户登录。",
"oauthsignin": "尝试使用其他账户登录。",
"redirect_uri_mismatch": "重定向 URI 与 OAuth 应用程序配置不匹配。",
"oauthcallbackerror": "尝试使用其他账户登录。",
"oauthcreateaccount": "尝试使用其他账户登录。",
"emailcreateaccount": "尝试使用其他账户登录。",
"callback": "尝试使用其他账户登录。",
"oauthaccountnotlinked": "要确认您的身份,请使用您最初使用的同一账户登录。",
"emailsignin": "无法发送电子邮件。",
"emailverify": "请验证您的电子邮件,新邮件已发送。",
"credentialssignin": "登录失败。请检查您提供的详细信息是否正确。",
"sessionrequired": "请登录以访问此页面。"
}
},
"authVerifyEmail": {
"almostThere": "您快完成了!我们已发送电子邮件至",
"verifyEmailLink": "请点击该电子邮件中的链接以完成注册。",
"didNotReceive": "找不到电子邮件?",
"resendEmail": "重新发送电子邮件",
"goBack": "返回",
"emailSent": "电子邮件发送成功。",
"verifyEmail": "验证您的电子邮件地址"
},
"providerButton": {
"continue": "继续使用{{provider}}",
"signup": "使用{{provider}}注册"
},
"authResetPassword": {
"newPasswordRequired": "新密码是必填字段",
"passwordsMustMatch": "密码必须匹配",
"confirmPasswordRequired": "确认密码是必填字段",
"newPassword": "新密码",
"confirmPassword": "确认密码",
"resetPassword": "重置密码"
},
"authForgotPassword": {
"email": "电子邮件地址",
"emailRequired": "电子邮件是必填字段",
"emailSent": "请检查电子邮件地址 {{email}} 以获取重置密码的说明。",
"enterEmail": "输入您的电子邮件地址,我们将发送重置密码的说明。",
"resendEmail": "重新发送电子邮件",
"continue": "继续",
"goBack": "返回"
}
}
},
"organisms": {
"chat": {
"history": {
"index": {
"showHistory": "显示历史记录",
"lastInputs": "上次输入",
"noInputs": "空空如也...",
"loading": "加载中..."
}
},
"inputBox": {
"input": {
"placeholder": "在此输入您的消息..."
},
"speechButton": {
"start": "开始录音",
"stop": "停止录音"
},
"SubmitButton": {
"sendMessage": "发送消息",
"stopTask": "停止任务"
},
"UploadButton": {
"attachFiles": "附件文件"
},
"waterMark": {
"text": "由codegeex团队提供支持"
}
},
"Messages": {
"index": {
"running": "运行中",
"executedSuccessfully": "执行成功",
"failed": "失败",
"feedbackUpdated": "反馈已更新",
"updating": "更新中"
}
},
"dropScreen": {
"dropYourFilesHere": "将文件拖放到此处"
},
"index": {
"failedToUpload": "上传失败",
"cancelledUploadOf": "取消上传",
"couldNotReachServer": "无法连接服务器",
"continuingChat": "继续先前的聊天"
},
"settings": {
"settingsPanel": "设置面板",
"reset": "重置",
"cancel": "取消",
"confirm": "确认"
}
},
"threadHistory": {
"sidebar": {
"filters": {
"FeedbackSelect": {
"feedbackAll": "反馈:全部",
"feedbackPositive": "反馈:正面",
"feedbackNegative": "反馈:负面"
},
"SearchBar": {
"search": "搜索"
}
},
"DeleteThreadButton": {
"confirmMessage": "这将删除线程及其消息和元素。",
"cancel": "取消",
"confirm": "确认",
"deletingChat": "删除聊天中",
"chatDeleted": "聊天已删除"
},
"index": {
"pastChats": "过去的聊天"
},
"ThreadList": {
"empty": "空的...",
"today": "今天",
"yesterday": "昨天",
"previous7days": "前7天",
"previous30days": "前30天"
},
"TriggerButton": {
"closeSidebar": "关闭侧边栏",
"openSidebar": "打开侧边栏"
}
},
"Thread": {
"backToChat": "返回聊天",
"chatCreatedOn": "此聊天创建于"
}
},
"header": {
"chat": "聊天",
"readme": "自述文件"
}
}
},
"hooks": {
"useLLMProviders": {
"failedToFetchProviders": "无法获取提供者:"
}
},
"pages": {
"Design": {},
"Env": {
"savedSuccessfully": "保存成功",
"requiredApiKeys": "所需 API 密钥",
"requiredApiKeysInfo": "要使用此应用程序,需要以下 API 密钥。这些密钥存储在您设备的本地存储中。"
},
"Page": {
"notPartOfProject": "您不属于此项目。"
},
"ResumeButton": {
"resumeChat": "继续聊天"
}
}
}

35
repodemo/chainlit.md Normal file
View File

@ -0,0 +1,35 @@
# CodeGeeX
# Welcome to use my chat dome application
This is a simple demonstration application.
## Usage
1. Enter your question
2. Wait for the reply
3. Enjoy the conversation!
## Features
- Support multi-round dialogue
- Support uploading local zip compressed project package, and can perform project question and answer and modify the project
## Installation
1. Clone the repository to your local machine
2. Install dependencies: `pip install -r requirements.txt`
3. Run the application: `python run.py`
## Note
Please ensure that your network environment can access the CodeGeeX API.
## Disclaimer
This application is for learning and research purposes only and shall not be used for any commercial purposes. The developer is not responsible for any loss or damage caused by the use of this application.
## Thank you
Thank you for using our application. If you have any questions or suggestions, please feel free to contact us. We look forward to your feedback and are committed to providing you with better services.

View File

@ -0,0 +1,34 @@
# CodeGeeX
# 欢迎使用我的chat dome应用
这是一个简单的演示应用程序。
## 使用说明
1. 输入您的问题
2. 等待回复
3. 享受对话!
## 功能
- 支持多轮对话
- 支持上传本地zip压缩包项目可以进行项目问答和对项目进行修改
## 安装
1. 克隆仓库到本地
2. 安装依赖:`pip install -r requirements.txt`
3. 运行应用:`chain run run.py --port 8888`
## 注意
请确保您的网络环境可以访问CodeGeeX的API。
## 免责声明
本应用仅供学习和研究使用,不得用于任何商业用途。开发者不对因使用本应用而导致的任何损失或损害负责。
## 感谢
感谢您使用我们的应用。如果您有任何问题或建议,请随时联系我们。我们期待您的反馈,并致力于为您提供更好的服务。

View File

@ -0,0 +1,41 @@
import requests
import json
URL = "" #the url you deploy codegeex service
def codegeex4(prompt, temperature=0.8, top_p=0.8):
url = URL
headers = {
'Content-Type': 'application/json'
}
data = {
'inputs': prompt,
'parameters': {
'best_of':1,
'do_sample': True,
'max_new_tokens': 4012,
'temperature': temperature,
'top_p': top_p,
'stop': ["<|endoftext|>", "<|user|>", "<|observation|>", "<|assistant|>"],
}
}
response = requests.post(url, json=data, headers=headers, verify=False, stream=True)
if response.status_code == 200:
for line in response.iter_lines():
if line:
decoded_line = line.decode('utf-8').replace('data:', '').strip()
if decoded_line:
try:
content = json.loads(decoded_line)
token_text = content.get('token', {}).get('text', '')
if '<|endoftext|>' in token_text:
break
yield token_text
except json.JSONDecodeError:
continue
else:
print('请求失败:', response.status_code)

View File

@ -0,0 +1,42 @@
base_system_prompt = """<|system|>\n你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。"""
repo_system_prompt = """<|system|>\n你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码。请根据用户给出的项目仓库中的代码以及用户提出的需求生成新的代码或者更改已有代码。输出格式\n\n###PATH:{PATH}\n{CODE}"""
judge_task_prompt = """<|system|>\n你是一位任务分类专家,请你对用户的输入进行分类(问答/修改/正常),如果用户的输入是对项目进行提问则只需要输出问答两个字,如果用户的输入是对项目进行修改或增加则只需要输出修改两个字,如果用户输入的是一个与项目无关的问题则只需要输出正常两个字。<|user|>\n{user_input}<|assistant|>\n"""
web_judge_task_prompt ="""<|system|>\n你是一位智能编程助手你叫CodeGeeX。你会为用户回答关于编程、代码、计算机方面的任何问题并提供格式规范、可以执行、准确安全的代码并在必要时提供详细的解释。<|user|>\n{user_input}\n这个问题需要进行联网来回答吗?仅回答“是”或者“否”。<|assistant|>\n"""
# judge_task_prompt = """<|system|>\n你是一位任务分类专家请你对用户的输入进行分类问答/修改),如果用户的输入是对项目进行提问则只需要输出问答两个字,如果用户的输入是对项目进行修改或增加则只需要输出修改两个字。<|user|>\n{user_input}<|assistant|>\n"""
web_search_prompy = """
你将接收到一个用户提出的问题并请撰写清晰简洁且准确的答案
# Note
- 您将获得与问题相关的多个上下文片段每个上下文都以引用编号开头例如[[citation:x]]其中x是一个数字如果适用请使用上下文并在每个句子的末尾引用上下文
- 您的答案必须是正确的准确的并且以专家的身份使用无偏见和专业的语调来撰写
- 请你的回答限制在2千字以内不要提供与问题无关的信息也不要重复
- 请以引用编号的格式[[citation:x]]来引用上下文如果一个句子来自多个上下文请列出所有适用的引用例如[[citation:3]][[citation:5]]
- 若所有上下文均不相关请以自己的理解回答用户提出的问题此时回答中可以不带引用编号
- 除了代码和特定的名称和引用外您的答案必须使用与问题相同的语言来撰写
""".lstrip()
def get_cur_base_user_prompt(message_history,index_prompt = None,judge_context = ""):
user_prompt_tmp = """<|user|>\n{user_input}"""
assistant_prompt_tmp = """<|assistant|>\n{assistant_input}"""
history_prompt = ""
for i,message in enumerate(message_history):
if message['role'] == 'user':
if i==0 and index_prompt is not None:
history_prompt += "<|user|>\n"+index_prompt+message['content']
else:
history_prompt += user_prompt_tmp.format(user_input=message['content'])
elif message['role'] == 'assistant':
history_prompt += assistant_prompt_tmp.format(assistant_input=message['content'])
# print("修改" not in judge_context)
# print(judge_context)
if "修改" not in judge_context:
result = base_system_prompt+history_prompt+"""<|assistant|>\n"""
else:
result = repo_system_prompt+history_prompt+"""<|assistant|>\n"""
print(result)
return result

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
repodemo/public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

26
repodemo/readme.md Normal file
View File

@ -0,0 +1,26 @@
# CodeGeeX
# 欢迎使用我的chat dome应用
这是一个简单的演示应用程序。
## 使用说明
1. 输入您的问题
2. 等待回复
3. 享受对话!
## 功能
- 支持多轮对话
- 支持上传本地zip压缩包项目可以进行项目问答和对项目进行修改
## 安装
1. 克隆仓库到本地
2. 安装依赖:`pip install -r requirements.txt`
3. 运行应用:`chainlit run run.py --port 8888`
## 注意
请确保您的网络环境可以访问CodeGeeX的API。

View File

@ -0,0 +1,2 @@
chainlit==1.1.305
beautifulsoup4

157
repodemo/run.py Normal file
View File

@ -0,0 +1,157 @@
import chainlit as cl
from chainlit.input_widget import Slider
from llm.api.codegeex4 import codegeex4
from prompts.base_prompt import judge_task_prompt,get_cur_base_user_prompt,web_judge_task_prompt
from utils.tools import unzip_file,get_project_files_with_content
from utils.bingsearch import bing_search_prompt
@cl.set_chat_profiles
async def chat_profile():
return [
cl.ChatProfile(
name="chat聊天",
markdown_description="聊天demo支持多轮对话。",
starters = [
cl.Starter(
label="请你用python写一个快速排序。",
message="请你用python写一个快速排序。",
),
cl.Starter(
label="请你介绍一下自己。",
message="请你介绍一下自己。",
),
cl.Starter(
label="用 Python 编写一个脚本来自动发送每日电子邮件报告,并指导我如何进行设置。",
message="用 Python 编写一个脚本来自动发送每日电子邮件报告,并指导我如何进行设置。",
),
cl.Starter(
label="我是一个python初学者请你告诉我怎么才能学好python。",
message="我是一个python初学者请你告诉我怎么才能学好python。",
)
]
),
cl.ChatProfile(
name="联网问答",
markdown_description="联网能力dome支持联网回答用户问题。",
),
cl.ChatProfile(
name="上传本地项目",
markdown_description="项目级能力dome支持上传本地zip压缩包项目可以进行项目问答和对项目进行修改。",
)
]
@cl.on_chat_start
async def start():
settings = await cl.ChatSettings(
[
Slider(
id="temperature",
label="CodeGeeX4 - Temperature",
initial=0.2,
min=0,
max=1,
step=0.1,
),
Slider(
id="top_p",
label="CodeGeeX4 - top_p",
initial=0.95,
min=0,
max=1,
step=0.1,
),
]
).send()
temperature = settings["temperature"]
top_p = settings["top_p"]
cl.user_session.set('temperature',temperature)
cl.user_session.set('top_p',top_p)
cl.user_session.set(
"message_history",
[]
)
chat_profile = cl.user_session.get("chat_profile")
extract_dir = 'repodata'
if chat_profile == "chat聊天":
pass
elif chat_profile =="上传本地项目":
files = None
while files == None:
files = await cl.AskFileMessage(
content="请上传项目zip压缩文件!", accept={"application/zip": [".zip"]},max_size_mb=50
).send()
text_file = files[0]
extracted_path = unzip_file(text_file.path,extract_dir)
files_list = get_project_files_with_content(extracted_path)
cl.user_session.set("project_index",files_list)
if len(files_list)>0:
await cl.Message(
content=f"已成功上传,您可以开始对项目进行提问!",
).send()
@cl.on_message
async def main(message: cl.Message):
chat_profile = cl.user_session.get("chat_profile")
message_history = cl.user_session.get("message_history")
message_history.append({"role": "user", "content": message.content})
if chat_profile == "chat聊天":
prompt_content = get_cur_base_user_prompt(message_history=message_history)
elif chat_profile=="联网问答":
judge_tmp = codegeex4(web_judge_task_prompt.format(user_input=message.content),temperature=0.2,top_p = 0.95)
judge_context = '\n'.join(judge_tmp)
print(judge_context)
message_history.pop()
if '' in judge_context:
prompt_tmp = bing_search_prompt(message.content)
message_history.append({"role": "user", "content": prompt_tmp})
else:
message_history.append({"role": "user", "content": message.content})
prompt_content = get_cur_base_user_prompt(message_history=message_history)
elif chat_profile =="上传本地项目" :
judge_tmp = codegeex4(judge_task_prompt.format(user_input=message.content),temperature=0.2,top_p = 0.95)
judge_context = ''
for part in judge_tmp:
judge_context+=part
project_index = cl.user_session.get("project_index")
index_prompt = ""
index_tmp = """###PATH:{path}\n{code}\n"""
for index in project_index:
index_prompt+=index_tmp.format(path=index['path'],code=index['content'])
print(judge_context)
prompt_content = get_cur_base_user_prompt(message_history=message_history,index_prompt=index_prompt,judge_context=judge_context) if '正常' not in judge_context else get_cur_base_user_prompt(message_history=message_history)
msg = cl.Message(content="")
await msg.send()
temperature = cl.user_session.get("temperature")
top_p = cl.user_session.get('top_p')
if len(prompt_content)/4<120000:
stream = codegeex4(prompt_content,temperature=temperature,top_p = top_p)
for part in stream:
if token := (part or " "):
await msg.stream_token(token)
else:
await msg.stream_token("项目太大了,请换小一点的项目。")
message_history.append({"role": "assistant", "content": msg.content})
await msg.update()

19
repodemo/utils/keep.txt Normal file
View File

@ -0,0 +1,19 @@
package-lock.json
package.json
config.json
LICENSE
yarn.lock
requirements.txt
Dockerfile
build.gradle
Makefile
go.mod
go.sum
CHANGES.txt
Cargo.toml
pubspec.yaml
root.json
snapshot.json
targets.json
timestamp.json
Cargo.lock

File diff suppressed because one or more lines are too long

154
repodemo/utils/tools.py Normal file
View File

@ -0,0 +1,154 @@
import zipfile
import os
import json
def unzip_file(zip_path, extract_dir):
"""
解压zip文件到指定目录并在指定目录下创建一个新的目录存放解压后的文件
参数:
zip_path (str): zip压缩包的地址
extract_dir (str): 指定解压的目录
返回:
str: 解压后的路径
"""
if not os.path.exists(extract_dir):
os.makedirs(extract_dir)
base_name = os.path.basename(zip_path)
dir_name = os.path.splitext(base_name)[0]
new_extract_dir = os.path.join(extract_dir, dir_name)
if not os.path.exists(new_extract_dir):
os.makedirs(new_extract_dir)
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(new_extract_dir)
return new_extract_dir
def get_project_files_with_content(project_dir):
"""
获取项目目录下所有文件的相对路径和内容
参数:
project_dir (str): 项目目录地址
返回:
list: 包含字典的列表每个字典包含文件的相对路径和内容
"""
files_list = []
for root, dirs, files in os.walk(project_dir):
for file in files:
if filter_data(file):
file_path = os.path.join(root, file)
relative_path = os.path.relpath(file_path, project_dir)
if "__MACOSX" in relative_path:
continue
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
files_list.append({'path': relative_path, 'content': content})
else:
continue
return files_list
def filter_data(obj):
LANGUAGE_TAG = {
"c++" : "// C++",
"cpp" : "// C++",
"c" : "// C",
"c#" : "// C#",
"c-sharp" : "// C#",
"css" : "/* CSS */",
"cuda" : "// Cuda",
"fortran" : "! Fortran",
"go" : "// Go",
"html" : "<!-- HTML -->",
"java" : "// Java",
"js" : "// JavaScript",
"javascript" : "// JavaScript",
"kotlin" : "// Kotlin",
"lean" : "-- Lean",
"lua" : "-- Lua",
"objectivec" : "// Objective-C",
"objective-c" : "// Objective-C",
"objective-c++": "// Objective-C++",
"pascal" : "// Pascal",
"php" : "// PHP",
"python" : "# Python",
"r" : "# R",
"rust" : "// Rust",
"ruby" : "# Ruby",
"scala" : "// Scala",
"shell" : "# Shell",
"sql" : "-- SQL",
"tex" : f"% TeX",
"typescript" : "// TypeScript",
"vue" : "<!-- Vue -->",
"assembly" : "; Assembly",
"dart" : "// Dart",
"perl" : "# Perl",
"prolog" : f"% Prolog",
"swift" : "// swift",
"lisp" : "; Lisp",
"vb" : "' Visual Basic",
"visual basic" : "' Visual Basic",
"matlab" : f"% Matlab",
"delphi" : "{ Delphi }",
"scheme" : "; Scheme",
"basic" : "' Basic",
"assembly" : "; Assembly",
"groovy" : "// Groovy",
"abap" : "* Abap",
"gdscript" : "# GDScript",
"haskell" : "-- Haskell",
"julia" : "# Julia",
"elixir" : "# Elixir",
"excel" : "' Excel",
"clojure" : "; Clojure",
"actionscript" : "// ActionScript",
"solidity" : "// Solidity",
"powershell" : "# PowerShell",
"erlang" : f"% Erlang",
"cobol" : "// Cobol",
"batchfile" : ":: Batch file",
"makefile" : "# Makefile",
"dockerfile" : "# Dockerfile",
"markdown" : "<!-- Markdown -->",
"cmake" : "# CMake",
"dockerfile" : "# Dockerfile",
}
programming_languages_to_file_extensions = json.load(open('utils/programming-languages-to-file-extensions.json'))
need2del = []
for key in programming_languages_to_file_extensions.keys():
if key.lower() not in LANGUAGE_TAG:
need2del.append(key)
for key in need2del:
del programming_languages_to_file_extensions[key]
ext_to_programming_languages = {}
want_languages = []
for key in programming_languages_to_file_extensions:
for item in programming_languages_to_file_extensions[key]:
ext_to_programming_languages[item] = key
want_languages.append(item)
ext = '.'+obj.split('.')[-1]
with open('utils/keep.txt', 'r') as f:
keep_files = f.readlines()
keep_files = [l.strip() for l in keep_files]
#print(ext)
if ext not in want_languages:
if obj in keep_files:
return True
return False
else:
return True

BIN
resources/all_functions.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

BIN
resources/logo.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

34
web_demo/README.md Normal file
View File

@ -0,0 +1,34 @@
![](../resources/logo.jpeg)
[English](README.md) | [中文](README_zh.md)
## Online Functionality
CodeGeeX4 supports online search and question answering by calling the Bing API to retrieve search results to access to the latest
information.
## Usage Tutorial
### 1. Install Dependencies
```bash
pip install -r requirements.txt
```
### 2. Configure Bing API Key
Configure `BING_API_KEY` in `backend/apis/bing.py`.
For more details, refer
to [Bing Search API](https://learn.microsoft.com/zh-cn/previous-versions/azure/cognitive-services/Bing-Web-Search/bing-api-comparison)
### 3. Run the Project
```bash
python main.py
>>> Running on local URL: http://127.0.0.1:8080
```
## Demo
![](resources/demo.png)

33
web_demo/README_zh.md Normal file
View File

@ -0,0 +1,33 @@
![](../resources/logo.jpeg)
[English](README.md) | [中文](README_zh.md)
## 联网功能
CodeGeeX4支持联网搜索问答通过调用Bing API获取搜索结果可获取最新资讯。
## 使用教程
### 1. 安装依赖项
```bash
pip install -r requirements.txt
```
### 2. 配置Bing API Key
在`backend/apis/bing.py`中配置`BING_API_KEY`
详情可参考 [必应搜索API](https://learn.microsoft.com/zh-cn/previous-versions/azure/cognitive-services/Bing-Web-Search/bing-api-comparison)
### 3. 运行项目
```bash
python main.py
>>> Running on local URL: http://127.0.0.1:8080
```
## Demo
![](resources/demo_zh.png)

View File

@ -0,0 +1,12 @@
class API:
def call(self, **kwargs):
return self.__call__(**kwargs)
def __call__(self, **kwargs):
search_kwargs = {'query': kwargs['query'], 'freshness': 'month'}
search_res = self.search(**search_kwargs)
return search_res
@classmethod
def search(cls, **kwargs) -> list[str]:
raise NotImplementedError

View File

@ -0,0 +1,43 @@
"""
Bing Search
"""
import os
import requests
from backend.apis.api import API
BING_API_KEY = os.getenv('BING_API_KEY')
class BingSearchAPI(API):
def __init__(self):
self.url = "https://api.bing.microsoft.com/v7.0/search"
def search(self, query, freshness=None):
"""
Search with bing
References: https://docs.microsoft.com/en-us/bing/search-apis/bing-web-search/overview
"""
response = requests.get(
url=self.url,
headers={"Ocp-Apim-Subscription-Key": BING_API_KEY},
params={
"q": query,
"mkt": 'zh-CN',
"freshness": freshness,
},
timeout=10,
)
try:
json_content = response.json()
contexts = json_content['webPages']['value'][:4]
search_res = [{
"url": item['url'],
"title": item['name'],
"snippet": item['snippet']
} for item in contexts]
return search_res
except Exception as e:
print(f"Searching failed, caused by {e}")
return []

View File

@ -0,0 +1,10 @@
import torch
from transformers import AutoTokenizer, AutoModel
device = "cuda" if torch.cuda.is_available() else "cpu"
model_name_or_path = "THUDM/codegeex4-all-9b"
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, trust_remote_code=True)
model = AutoModel.from_pretrained(
model_name_or_path,
trust_remote_code=True
).to(device).eval()

View File

@ -0,0 +1,35 @@
import json
from backend.apis.api import API
from backend.apis.bing import BingSearchAPI
from backend.models.codegeex import model, tokenizer
from backend.utils.chat import build_model_input, SYS_PROMPT
def chat(query: str, history: list[list[str]] = None):
if not history:
history = []
ans = ""
# Search with bing
api: API = BingSearchAPI()
search_res = api.call(query=query, history=history)
ans += "搜索结果".center(100, "-") + '\n'
ans += "```json\n" + json.dumps(search_res, indent=4, ensure_ascii=False) + "\n```\n"
yield ans
# Build model's input
inputs: str = build_model_input(query, search_res)
# Generate response
ans += "模型回复".center(100, "-") + '\n'
yield ans
response, _ = model.chat(
tokenizer,
query=inputs,
history=[{"role": "system", "content": SYS_PROMPT}],
max_new_tokens=1024,
temperature=0.2
)
yield ans + response

View File

@ -0,0 +1,26 @@
SYS_PROMPT = """
你将接收到一个用户提出的问题并请撰写清晰简洁且准确的答案
# Note
- 您将获得与问题相关的多个上下文片段每个上下文都以引用编号开头例如[[citation:x]]其中x是一个数字如果适用请使用上下文并在每个句子的末尾引用上下文
- 您的答案必须是正确的准确的并且以专家的身份使用无偏见和专业的语调来撰写
- 请你的回答限制在2千字以内不要提供与问题无关的信息也不要重复
- 请以引用编号的格式[[citation:x]]来引用上下文如果一个句子来自多个上下文请列出所有适用的引用例如[[citation:3]][[citation:5]]
- 若所有上下文均不相关请以自己的理解回答用户提出的问题此时回答中可以不带引用编号
- 除了代码和特定的名称和引用外您的答案必须使用与问题相同的语言来撰写
""".lstrip()
def build_model_input(query, search_res):
"""
Build model's input
:param query: user query
:param search_res: bing's search results
:return:
"""
citations = "\n\n".join(
[f"[[citation:{i + 1}]]\n```markdown\n{item['snippet']}\n```" for i, item in enumerate(search_res)]
)
prompt = f"[引用]\n{citations}\n问:{query}\n"
return prompt

10
web_demo/main.py Normal file
View File

@ -0,0 +1,10 @@
"""
References: https://github.com/leptonai/search_with_lepton
"""
import gradio as gr
from backend.services.chat import chat
if __name__ == "__main__":
demo = gr.ChatInterface(chat).queue()
demo.launch(server_name="127.0.0.1", server_port=8080)

View File

@ -0,0 +1,7 @@
accelerate==0.31.0
gradio==4.26.0
regex==2024.5.15
requests==2.32.3
tiktoken==0.7.0
torch==2.3.1
transformers==4.39.0

BIN
web_demo/resources/demo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 KiB