Hoje, estamos entusiasmados em abrir o código-fonte da série “Poderoso”, “Diverso” e “Prático” Qwen2.5-Coder (anteriormente conhecido como CodeQwen1.5), dedicado a promover continuamente o desenvolvimento de Open CodeLLMs.
Poderoso: Qwen2.5-Coder-32B-Instruct tornou-se o atual modelo de código-fonte aberto SOTA, correspondendo aos recursos de codificação do GPT-4o. Embora demonstre habilidades de codificação fortes e abrangentes, também possui boas habilidades gerais e matemáticas;
Diversificado: Com base nos dois tamanhos de 1,5B/7B, anteriormente de código aberto, esta versão traz quatro tamanhos de modelo, incluindo 0,5B/3B/14B/32B. Até agora, o Qwen2.5-Coder cobriu seis tamanhos de modelos convencionais para atender às necessidades de diferentes desenvolvedores;
? Prático: Exploramos a praticidade do Qwen2.5-Coder em dois cenários, incluindo assistentes de código e artefatos, com alguns exemplos mostrando as aplicações potenciais do Qwen2.5-Coder em cenários do mundo real;
Suportando compreensão e geração de contexto longo com comprimento de contexto de tokens de 128K;
Suporta 92 linguagens de codificação;
['ada', 'agda', 'alloy', 'antlr', 'applescript', 'assembly', 'augeas', 'awk', 'batchfile', 'bluespec', 'c', 'c#', 'c++', 'clojure', 'cmake', 'coffeescript', 'common-lisp', 'css', 'cuda', 'dart', 'dockerfile', 'elixir', 'elm', 'emacs-lisp', 'erlang', 'f#', 'fortran', 'glsl', 'go', 'groovy', 'haskell', 'html', 'idris', 'isabelle', 'java', 'java-server-pages', 'javascript', 'json', 'julia', 'jupyter-notebook', 'kotlin', 'lean', 'literate-agda', 'literate-coffeescript', 'literate-haskell', 'lua', 'makefile', 'maple', 'markdown', 'mathematica', 'matlab', 'objectc++', 'ocaml', 'pascal', 'perl', 'php', 'powershell', 'prolog', 'protocol-buffer', 'python', 'r', 'racket', 'restructuredtext', 'rmarkdown', 'ruby', 'rust', 'sas', 'scala', 'scheme', 'shell', 'smalltalk', 'solidity', 'sparql', 'sql', 'stan', 'standard-ml', 'stata', 'swift', 'systemverilog', 'tcl', 'tcsh', 'tex', 'thrift', 'typescript', 'verilog', 'vhdl', 'visual-basic', 'vue', 'xslt', 'yacc', 'yaml', 'zig']
Manter os pontos fortes em matemática e capacidades gerais do modelo básico
Importante
Atualizamos os tokens especiais e seus IDs de token correspondentes, para manter a consistência com o Qwen2.5. Os novos tokens especiais são os seguintes:
{ "<|fim_prefix|>": 151659, "<|fim_middle|>": 151660, "<|fim_suffix|>": 151661, "<|fim_pad|>": 151662, "<|repo_name|>": 151663, "<|file_sep|>": 151664, "<|im_start|>": 151644, "<|im_end|>": 151645}
nome do modelo | tipo | comprimento | Download |
---|---|---|---|
Qwen2.5-Codificador-0.5B | base | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Codificador-1.5B | base | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Codificador-3B | base | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Codificador-7B | base | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Codificador-14B | base | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Codificador-32B | base | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-0.5B-instrução | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-1.5B-instrução | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-3B-instrução | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-7B-instrução | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-14B-instrução | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-32B-instrução | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-0.5B-Instruct-AWQ | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-0.5B-Instruct-GGUF | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-0.5B-Instruct-GPTQ-Int4 | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-0.5B-Instruct-GPTQ-Int8 | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-1.5B-Instruct-AWQ | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-1.5B-Instruir-GGUF | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-1.5B-Instruct-GPTQ-Int4 | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-1.5B-Instruct-GPTQ-Int8 | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-3B-Instruct-AWQ | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-3B-Instruir-GGUF | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-3B-Instruct-GPTQ-Int4 | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-3B-Instruct-GPTQ-Int8 | instruir | 32k | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-7B-Instruct-AWQ | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-7B-Instruir-GGUF | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-7B-Instruct-GPTQ-Int4 | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-7B-Instruct-GPTQ-Int8 | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-14B-Instruct-AWQ | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-14B-Instruir-GGUF | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-14B-Instruct-GPTQ-Int4 | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-14B-Instruct-GPTQ-Int8 | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-32B-Instruct-AWQ | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-32B-Instruct-GGUF | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-32B-Instruct-GPTQ-Int4 | instruir | 128 mil | Rosto Abraçado • ModelScope |
Qwen2.5-Coder-32B-Instruct-GPTQ-Int8 | instruir | 128 mil | Rosto Abraçado • ModelScope |
Desempenho detalhado e introdução são mostrados neste? blog.
python>=3.9
transformers>4.37.0
para modelos densos Qwen2.5.
Aviso
Isto é obrigatório porque os `transformers` integraram códigos Qwen2 desde `4.37.0`.
Você pode instalar os pacotes necessários com o seguinte comando:
pip instalar -r requisitos.txt
Importante
Qwen2.5-Coder-[0.5-32]B-Instrcut são modelos de instruções para bate-papo;
Qwen2.5-Coder-[0.5-32]B é um modelo básico normalmente usado para conclusão, servindo como um melhor ponto de partida para o ajuste fino.
Você pode simplesmente escrever várias linhas de código com transformers
para conversar com Qwen2.5-Coder-32B-Instruct. Essencialmente, construímos o tokenizer e o modelo com o método from_pretrained
e usamos o método generate para realizar o bate-papo com a ajuda do modelo de bate-papo fornecido pelo tokenizer. Abaixo está um exemplo de como conversar com Qwen2.5-Coder-32B-Instruct:
dos transformadores importar AutoModelForCausalLM, AutoTokenizermodel_name = "Qwen/Qwen2.5-Coder-32B-Instruct"model = AutoModelForCausalLM.from_pretrained(model_name,torch_dtype="auto",device_map="auto")tokenizer = AutoTokenizer.from_pretrained(model_name)prompt = "escreva um algoritmo de classificação rápida."messages = [ {"role": "system", "content": "Você é Qwen, criado por Alibaba Cloud. Você é um assistente útil."}, {"role": "usuário", "content": prompt} ]text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True)model_inputs = tokenizer([text], return_tensors="pt").to(model.device)generated_ids = model.generate(**model_inputs,max_new_tokens= 512)generated_ids = [output_ids[len(input_ids):] para input_ids, output_ids em zip(model_inputs.input_ids, generate_ids) ]resposta = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
A função apply_chat_template()
é usada para converter as mensagens em um formato que o modelo possa entender. O argumento add_generation_prompt
é usado para adicionar um prompt de geração, que se refere ao <|im_start|>assistantn
à entrada. Notavelmente, aplicamos o modelo ChatML para modelos de chat seguindo nossa prática anterior. O argumento max_new_tokens
é usado para definir o comprimento máximo da resposta. A função tokenizer.batch_decode()
é usada para decodificar a resposta. Em termos de entrada, as mensagens acima são um exemplo para mostrar como formatar seu histórico de diálogo e prompt do sistema. Você pode usar o outro tamanho do modelo de instrução da mesma maneira.
O modelo completa os trechos de código de acordo com os prompts fornecidos, sem qualquer formatação adicional, o que geralmente é denominado code completion
nas tarefas de geração de código.
Essencialmente, construímos o tokenizer e o modelo com o método from_pretrained
e usamos o método generate para realizar a conclusão do código. Abaixo está um exemplo de como conversar com Qwen2.5-Coder-32B:
from transformers import AutoTokenizer, AutoModelForCausalLMdevice = "cuda" # o dispositivo para carregar o modelo# Agora você não precisa adicionar "trust_remote_code=True"TOKENIZER = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-Coder-32B")MODEL = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-Coder-32B", device_map="auto").eval()# tokenize a entrada em tokensinput_text = "#write um algoritmo de classificação rápida"model_inputs = TOKENIZER([input_text], return_tensors ="pt").to(device)# Use `max_new_tokens` para controlar o comprimento máximo de saída.generated_ids = MODEL.generate(model_inputs.input_ids, max_new_tokens=512, do_sample=False)[0]# Os generate_ids incluem prompt_ids, então só precisamos decodificar os tokens após prompt_ids.output_text = TOKENIZER.decode(generated_ids[len(model_inputs.input_ids[ 0]):], skip_special_tokens=True)print(f"Prompt: {input_text}nnTexto gerado: {output_text}")
O argumento max_new_tokens
é usado para definir o comprimento máximo da resposta. O input_text
pode ser qualquer texto com o qual você gostaria que o modelo continuasse.
O config.json
atual está definido para comprimento de contexto de até 32.768 tokens. Para lidar com entradas extensas que excedem 32.768 tokens, utilizamos o YaRN, uma técnica para aprimorar a extrapolação do comprimento do modelo, garantindo desempenho ideal em textos longos.
Para estruturas suportadas, você pode adicionar o seguinte ao config.json
para ativar o YaRN:
{..., "rope_scaling": {"fator": 4.0,"original_max_position_embeddings": 32768,"type": "fio" } }
A tarefa de inserção de código, também conhecida como desafio "preencher o meio", requer a inserção de segmentos de código de uma maneira que preencha as lacunas dentro de um determinado contexto de código. Para uma abordagem alinhada com as melhores práticas, recomendamos aderir às diretrizes de formatação descritas no artigo "Treinamento Eficiente de Modelos de Linguagem para Preencher o Meio"[arxiv]. Isso envolve o uso de três tokens especializados
,
e
para denotar os respectivos segmentos da estrutura do código. O prompt deve ser estruturado da seguinte forma:
prompt = '<|fim_prefix|>' + prefix_code + '<|fim_suffix|>' + suffix_code + '<|fim_middle|>'
Seguindo a abordagem mencionada, um exemplo seria estruturado desta maneira:
from transformers import AutoTokenizer, AutoModelForCausalLM# load modeldevice = "cuda" # o dispositivo para carregar o modelo emTOKENIZER = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-Coder-32B")MODEL = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5 -Coder-32B", device_map="auto").eval()input_text = """<|fim_prefix|>def quicksort(arr): if len(arr) <= 1: return arr pivot = arr[len(arr) // 2] <|fim_suffix|> middle = [x for x in arr if x == pivô] direita = [x for x in arr if x > pivô] return quicksort(esquerda) + meio + quicksort(direita)<|fim_middle|>"""model_inputs = TOKENIZER([input_text], return_tensors="pt").to(device)# Use `max_new_tokens` para controlar o comprimento máximo de saída.generated_ids = MODEL.generate(model_inputs.input_ids, max_new_tokens=512, do_sample=False)[0] # Os generate_ids incluem prompt_ids, só precisamos decodificar os tokens após prompt_ids.output_text = TOKENIZER.decode(generated_ids[len(model_inputs.input_ids[0]):], skip_special_tokens=True)print(f"Prompt: {input_text}nnTexto gerado: {output_text}")
A tarefa de conclusão de código no nível do repositório envolve alimentar o modelo com o conteúdo de vários arquivos do mesmo repositório. Isso permite que o modelo entenda as inter-relações entre as diferentes chamadas dentro desses arquivos, facilitando assim a conclusão do conteúdo do código. Recomendamos usar os dois tokens especiais <|repo_name|>
e <|file_sep|>
para indicar a estrutura do repositório. Por exemplo, supondo que o nome do repositório esteja armazenado em repo_name
e contenha arquivos com seus respectivos caminhos e conteúdos listados como [( file_path1
, file_content1
), ( file_path2
, file_content2
)], o formato do prompt de entrada final seria o seguinte:
input_text = f'''<|repo_name|>{repo_name}<|file_sep|>{file_path1} {file_content1}<|file_sep|>{file_path2} {file_content2}'''
from transformers import AutoTokenizer, AutoModelForCausalLMdevice = "cuda" # o dispositivo para carregar o modelo# Agora você não precisa adicionar "trust_remote_code=True"TOKENIZER = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-Coder-32B")MODEL = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-Coder-32B", device_map="auto").eval()# tokeniza a entrada em tokensinput_text = """<|repo_name|>library-system<|file_sep|>library .pyclass Livro: def __init__(self, título, autor, isbn, cópias): self.title = título self.author = autor self.isbn = isbn self.copies = cópias def __str__(self): return f"Título: {self.title}, Autor: {self.author}, ISBN: {self.isbn}, Cópias: {self.copies}"class Library : def __init__(self): self.books = [] def add_book(self, título, autor, isbn, cópias): livro = Livro(título, autor, isbn, cópias) self.books.append(livro) def find_book(self, isbn): para livro em self.books: if book.isbn == isbn: return book return Nenhum def list_books(self): return self.books<|file_sep|>student.pyclass Aluno: def __init__( self, nome, id): self.name = nome self.id = id self.borrowed_books = [] def emprestado_book(self, livro, biblioteca): if book e book.copies > 0: self.borrowed_books.append(book) book.copies -= 1 return True return False def return_book(self, book, library): se livro em self.borrowed_books: self.borrowed_books.remove(book) book.copies += 1 return True return False<|file_sep|>main.pyfrom library import Libraryfrom student import Studentdef main(): # Configure a biblioteca com alguns livros library = Library() biblioteca.add_book("O Grande Gatsby", "F. Scott Fitzgerald", "1234567890", 3) biblioteca.add_book("To Kill a Mockingbird", "Harper Lee", "1234567891", 2) # Configurar um aluno student = Student("Alice", "S1") # Aluno pega um livro emprestado"""model_inputs = TOKENIZER([input_text], return_tensors="pt").to(device)# Use `max_new_tokens` para controlar o comprimento máximo de saída.generated_ids = MODEL.generate(model_inputs.input_ids, max_new_tokens=1024, do_sample=False)[0]# Os generate_ids incluem prompt_ids, então só precisamos decodificar os tokens após prompt_ids.output_text = TOKENIZER.decode(generated_ids[len(model_inputs.input_ids[0]):], skip_special_tokens=True)print(f"Prompt: n{input_text}nnTexto gerado: n{output_text}")
A saída esperada é a seguinte:
Texto gerado:livro = biblioteca.find_book("1234567890")if student.borrow_book(livro, biblioteca):print(f"{student.name} emprestado {book.title}")else:print(f"{student.name} emprestado } não foi possível pegar emprestado {book.title}") # Student retorna um livro se student.return_book(book, library):print(f"{student.name} retornou {book.title}")else:print(f"{student.name} não foi possível retornar {book.title}") # Lista todos os livros da bibliotecaprint("Todos os livros da biblioteca:")para o livro da biblioteca. list_books():print(book)if __name__ == "__main__":main()
Como membro da família Qwen2.5, o Qwen2.5-Coder é suportado pelo vLLM. O tutorial detalhado pode ser encontrado no tutorial Qwen. Aqui, damos a você um exemplo simples de inferência em lote offline no vLLM.
from transformers import AutoTokenizerfrom vllm import LLM, SamplingParams# Inicialize o tokenizertokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-Coder-32B")# Passe os hiperparâmetros de decodificação padrão de Qwen1.5-32B-Chat# max_tokens é para o máximo comprimento para geração.sampling_params = SamplingParams(temperature=0.7, top_p=0.8, repetition_penalty=1.05, max_tokens=1024)# Insira o nome ou caminho do modelo. Pode ser modelos GPTQ ou AWQ.llm = LLM(model="Qwen/Qwen2.5-Coder-32B")# Prepare seu promptsprompt = "#write um algoritmo de classificação rápida.ndef quick_sort("# generate outputsoutputs = llm.generate( [prompt], sampling_params)# Imprima as saídas.para saída em saídas:prompt = saída.promptgenerated_text = output.outputs[0].textprint(f"Prompt: {prompt!r}, Texto gerado: {generated_text!r}")
Para aumentar a capacidade de serviço, o serviço distribuído ajuda você a aproveitar mais dispositivos de GPU. Ao usar sequências ultralongas para inferência, isso pode causar memória GPU insuficiente. Aqui, demonstramos como executar Qwen2.5-Coder-32B com paralelismo tensorial apenas passando o argumento tensor_parallel_size
.
llm = LLM(model="Qwen/Qwen2.5-Coder-32B", tensor_parallel_size=8)
Também disponibilizamos uma interface Gradio para uma melhor experiência, bastando rodar por:
cd demo/chatbot/# Para usuários de Linux e Windows (e macOS com Intel??)python app.py # Para usuários de macOS com Apple Silicon, Intel não compatível, talvez 20x mais lento que RTX 4090PYTORCH_ENABLE_MPS_FALLBACK=1 python app.py
Também fornecemos uma interface Gradio do modo de artefatos:
CD de demonstração/artefatos/ aplicativo python.py
Você pode especificar os argumentos --server_port
, --share
, --server_name
para satisfazer suas necessidades!
Ou experimente sem esforço no HuggingFace: 「chatbot demo」 ? 「demonstração de artefatos」
Para obter mais informações, consulte o Relatório Técnico do Qwen2.5-Coder.
Se você achar nosso trabalho útil, sinta-se à vontade para nos enviar uma citação.
@artigo{hui2024qwen2, título={Qwen2. Relatório Técnico 5-Coder}, autor = {Hui, Binyuan e Yang, Jian e Cui, Zeyu e Yang, Jiaxi e Liu, Dayiheng e Zhang, Lei e Liu, Tianyu e Zhang, Jiajun e Yu, Bowen e Dang, Kai e outros}, diário={pré-impressão arXiv arXiv:2409.12186}, ano={2024}}@artigo{qwen2,title={Qwen2 Técnico Relatório}, autor = {An Yang e Baosong Yang e Binyuan Hui e Bo Zheng e Bowen Yu e Chang Zhou e Chengpeng Li e Chengyuan Li e Dayiheng Liu e Fei Huang e Guanting Dong e Haoran Wei e Huan Lin e Jialong Tang e Jialin Wang e Jian Yang e Jianhong Tu e Jianwei Zhang e Jianxin Ma e Jin Xu e Jingren Zhou e Jinze Bai e Jinzheng He e Junyang Lin e Kai Dang e Keming Lu e Keqin Chen e Kexin Yang e Mei Li e Mingfeng Xue e Na Ni e Pei Zhang e Peng Wang e Ru Peng e Rui Men e Ruize Gao e Runji Lin e Shijie Wang e Shuai Bai e Sinan Tan e Tianhang Zhu e Tianhao Li e Tianyu Liu e Wenbin Ge e Xiaodong Deng e Xiaohuan Zhou e Xingzhang Ren e Xinyu Zhang e Xipin Wei e Xuancheng Ren e Yang Fan e Yang Yao e Yichang Zhang e Yu Wan e Yunfei Chu e Yuqiong Liu e Zeyu Cui e Zhenru Zhang e Zhihao Fan},jornal={pré-impressão arXiv arXiv:2407.10671},ano={2024}}
Se você estiver interessado em deixar uma mensagem para nossa equipe de pesquisa ou de produto, junte-se aos nossos grupos Discord ou WeChat!
↑ Voltar ao início ↑