Hoy, estamos entusiasmados de poder abrir la serie Qwen2.5-Coder “poderosa”, “diversa” y “práctica” (anteriormente conocida como CodeQwen1.5), dedicada a promover continuamente el desarrollo de Open CodeLLM.
Potente: Qwen2.5-Coder-32B-Instruct se ha convertido en el modelo actual de código fuente abierto SOTA, igualando las capacidades de codificación de GPT-4o. Si bien demuestra habilidades de codificación sólidas y completas, también posee buenas habilidades generales y matemáticas;
Diverso: basándose en los dos tamaños de código abierto anteriores de 1.5B/7B, esta versión trae cuatro tamaños de modelo, incluidos 0.5B/3B/14B/32B. Hasta ahora, Qwen2.5-Coder ha cubierto seis tamaños de modelos principales para satisfacer las necesidades de diferentes desarrolladores;
? Práctico: exploramos la practicidad de Qwen2.5-Coder en dos escenarios, incluidos asistentes de código y artefactos, con algunos ejemplos que muestran las aplicaciones potenciales de Qwen2.5-Coder en escenarios del mundo real;
Admite la comprensión y generación de contextos prolongados con una longitud de contexto de 128 000 tokens;
Admite 92 lenguajes de codificación;
['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']
Conservar los puntos fuertes en matemáticas y capacidades generales del modelo base.
Importante
Actualizamos tanto los tokens especiales como sus correspondientes identificadores de tokens para mantener la coherencia con Qwen2.5. Los nuevos tokens especiales son los siguientes:
{ "<|prefijo_fim|>": 151659, "<|fim_middle|>": 151660, "<|sufijo_fim|>": 151661, "<|fim_pad|>": 151662, "<|nombre_repositorio|>": 151663, "<|archivo_sep|>": 151664, "<|im_start|>": 151644, "<|im_end|>": 151645}
nombre del modelo | tipo | longitud | Descargar |
---|---|---|---|
Qwen2.5-Codificador-0.5B | base | 32k | Cara abrazada • ModelScope |
Qwen2.5-Codificador-1.5B | base | 32k | Cara abrazada • ModelScope |
Qwen2.5-Codificador-3B | base | 32k | Cara abrazada • ModelScope |
Qwen2.5-Codificador-7B | base | 128k | Cara abrazada • ModelScope |
Qwen2.5-Codificador-14B | base | 128k | Cara abrazada • ModelScope |
Qwen2.5-Codificador-32B | base | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-0.5B-instrucciones | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-1.5B-instrucciones | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-3B-instrucción | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-7B-instrucción | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-14B-instrucción | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-32B-instrucciones | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-0.5B-Instruct-AWQ | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-0.5B-Instrucción-GGUF | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-0.5B-Instrucción-GPTQ-Int4 | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-0.5B-Instrucción-GPTQ-Int8 | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-1.5B-Instruct-AWQ | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-1.5B-Instrucción-GGUF | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-1.5B-Instrucción-GPTQ-Int4 | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-1.5B-Instrucción-GPTQ-Int8 | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-3B-Instrucción-AWQ | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-3B-Instrucción-GGUF | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-3B-Instrucción-GPTQ-Int4 | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-3B-Instrucción-GPTQ-Int8 | instruir | 32k | Cara abrazada • ModelScope |
Qwen2.5-Coder-7B-Instrucción-AWQ | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-7B-Instrucción-GGUF | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-7B-Instrucción-GPTQ-Int4 | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-7B-Instrucción-GPTQ-Int8 | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-14B-Instrucción-AWQ | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-14B-Instrucción-GGUF | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-14B-Instrucción-GPTQ-Int4 | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-14B-Instrucción-GPTQ-Int8 | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-32B-Instrucción-AWQ | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-32B-Instrucción-GGUF | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-32B-Instrucción-GPTQ-Int4 | instruir | 128k | Cara abrazada • ModelScope |
Qwen2.5-Coder-32B-Instrucción-GPTQ-Int8 | instruir | 128k | Cara abrazada • ModelScope |
En este documento se muestran el rendimiento y la introducción detallados. blog.
python>=3.9
transformers>4.37.0
para modelos densos Qwen2.5.
Advertencia
Esto es imprescindible porque los "transformers" integraron códigos Qwen2 desde "4.37.0".
Puede instalar los paquetes necesarios con el siguiente comando:
instalación de pip -r requisitos.txt
Importante
Qwen2.5-Coder-[0.5-32]B-Instrcut son modelos de instrucciones para chatear;
Qwen2.5-Coder-[0.5-32]B es un modelo base que normalmente se usa para completar y que sirve como un mejor punto de partida para el ajuste.
Puede simplemente escribir varias líneas de código con transformers
para chatear con Qwen2.5-Coder-32B-Instruct. Básicamente, construimos el tokenizador y el modelo con el método from_pretrained
y usamos el método generate para chatear con la ayuda de la plantilla de chat proporcionada por el tokenizador. A continuación se muestra un ejemplo de cómo chatear con Qwen2.5-Coder-32B-Instruct:
de transformadores importe 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 = "escribir un algoritmo de clasificación rápida."messages = [ {"role": "system", "content": "Eres Qwen, creado por Alibaba Cloud. Eres un asistente útil."}, {"rol": "usuario", "contenido": mensaje} ]text = tokenizer.apply_chat_template(messages,tokenize=False,add_spawn_prompt=True)model_inputs = tokenizer([text], return_tensors="pt").to(model.device)generated_ids = model.generate(**model_inputs,max_new_tokens= 512)id_generados = [id_salida[len(id_entrada):] para input_ids, output_ids en zip (model_inputs.input_ids, generate_ids) ]respuesta = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
La función apply_chat_template()
se utiliza para convertir los mensajes a un formato que el modelo pueda entender. El argumento add_generation_prompt
se utiliza para agregar un mensaje de generación, que hace referencia al <|im_start|>assistantn
a la entrada. En particular, aplicamos la plantilla ChatML para modelos de chat siguiendo nuestra práctica anterior. El argumento max_new_tokens
se utiliza para establecer la longitud máxima de la respuesta. La función tokenizer.batch_decode()
se utiliza para decodificar la respuesta. En términos de entrada, los mensajes anteriores son un ejemplo para mostrar cómo formatear su historial de diálogo y el mensaje del sistema. Puede utilizar el otro tamaño del modelo de instrucción de la misma manera.
El modelo completa los fragmentos de código de acuerdo con las indicaciones proporcionadas, sin ningún formato adicional, lo que generalmente se denomina code completion
en las tareas de generación de código.
Básicamente, construimos el tokenizador y el modelo con el método from_pretrained
y utilizamos el método generate para completar el código. A continuación se muestra un ejemplo de cómo chatear con Qwen2.5-Coder-32B:
desde transformadores importe AutoTokenizer, AutoModelForCausalLMdevice = "cuda" # el dispositivo para cargar el modelo# Ahora no necesita agregar "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()# tokenizar la entrada en tokensinput_text = "#escribir un algoritmo de clasificación rápida"model_inputs = TOKENIZER([input_text], return_tensors ="pt").to(device)# Utilice `max_new_tokens` para controlar la longitud máxima de salida.generated_ids = MODEL.generate(model_inputs.input_ids, max_new_tokens=512, do_sample=False)[0]# Los generate_ids incluyen Prompt_ids, por lo que solo necesitamos decodificar los tokens después de Prompt_ids.output_text = TOKENIZER.decode(generated_ids[len(model_inputs.input_ids[ 0]):], skip_special_tokens=True)print(f"Mensaje: {input_text}nnTexto generado: {output_text}")
El argumento max_new_tokens
se utiliza para establecer la longitud máxima de la respuesta. El input_text
podría ser cualquier texto con el que le gustaría que continuara el modelo.
El config.json
actual está configurado para una longitud de contexto de hasta 32,768 tokens. Para manejar entradas extensas que superan los 32,768 tokens, utilizamos YaRN, una técnica para mejorar la extrapolación de la longitud del modelo, garantizando un rendimiento óptimo en textos extensos.
Para los marcos compatibles, puede agregar lo siguiente a config.json
para habilitar YaRN:
{..., "rope_scaling": {"factor": 4.0,"original_max_position_embeddings": 32768,"type": "hilo" } }
La tarea de inserción de código, también conocida como el desafío "rellenar en el medio", requiere la inserción de segmentos de código de una manera que cierre las brechas dentro de un contexto de código determinado. Para un enfoque alineado con las mejores prácticas, recomendamos seguir las pautas de formato descritas en el documento "Efficient Training of Language Models to Fill in the Middle"[arxiv]. Esto implica el uso de tres tokens especializados
,
y
para indicar los respectivos segmentos de la estructura del código. El mensaje debe estructurarse de la siguiente manera:
símbolo = '<|fim_prefix|>' + prefijo_código + '<|fim_suffix|>' + sufijo_código + '<|fim_middle|>'
Siguiendo el enfoque mencionado, un ejemplo se estructuraría de esta manera:
desde transformadores importe AutoTokenizer, AutoModelForCausalLM# load modeldevice = "cuda" # el dispositivo para cargar el modelo enTOKENIZER = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-Coder-32B")MODEL = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5 -Coder-32B", dispositivo_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 == pivote] derecha = [x para x en arr if x > pivote] return clasificación rápida(izquierda) + medio + quicksort(right)<|fim_middle|>"""model_inputs = TOKENIZER([input_text], return_tensors="pt").to(device)# Utilice `max_new_tokens` para controlar la longitud máxima de salida.generated_ids = MODEL.generate(model_inputs .input_ids, max_new_tokens=512, do_sample=False)[0]# Los generate_ids incluyen Prompt_ids, solo necesitamos decodificar los tokens después de Prompt_ids.output_text = TOKENIZER.decode(generated_ids[len(model_inputs.input_ids[0]):], skip_special_tokens=True)print(f"Prompt: {input_text}nnTexto generado: {output_text }")
La tarea de completar el código a nivel de repositorio implica alimentar al modelo con el contenido de varios archivos del mismo repositorio. Esto permite que el modelo comprenda las interrelaciones entre diferentes llamadas dentro de estos archivos, facilitando así la finalización del contenido del código. Recomendamos utilizar los dos tokens especiales <|repo_name|>
y <|file_sep|>
para indicar la estructura del repositorio. Por ejemplo, suponiendo que el nombre del repositorio está almacenado en repo_name
y contiene archivos con sus respectivas rutas y contenidos listados como [( file_path1
, file_content1
), ( file_path2
, file_content2
)], el formato del mensaje de entrada final sería el siguiente:
input_text = f'''<|repo_name|>{repo_name}<|file_sep|>{file_path1} {file_content1}<|file_sep|>{file_path2} {file_content2}'''
desde transformadores importe AutoTokenizer, AutoModelForCausalLMdevice = "cuda" # el dispositivo para cargar el modelo# Ahora no necesita agregar "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 la entrada en tokensinput_text = """<|repo_name|>library-system<|file_sep|>library .pyclass Libro: def __init__(self, título, autor, isbn, copias): self.title = título self.author = autor self.isbn = isbn self.copies = copias def __str__(self): return f"Título: {self.title}, Autor: {self.author}, ISBN: {self.isbn}, Copias: {self.copies} "Biblioteca de clases: def __init__(self): self.books = [] def add_book(self, título, autor, isbn, copias): libro = Libro(título, autor, isbn, copias) self.books.append(book) def find_book(self, isbn): para libro en self.books: if book.isbn == isbn: devolver libro return Ninguno def list_books(self): devolver self.books<|file_sep |>student.pyclass Estudiante: def __init__(self, nombre, id): self.name = nombre self.id = id self.borrowed_books = [] def libro_prestado(self, libro, biblioteca): si libro y libro.copias > 0: self.borrowed_books.append(libro) libro.copias -= 1 return True return False def return_book(self, libro, biblioteca): si libro en self .borrowed_books: self.borrowed_books.remove(book) book.copies += 1 return True return False<|file_sep|>main.pyfrom importación de biblioteca Libraryfrom Student import Studentdef main(): # Configurar la biblioteca con algunos libros biblioteca = Biblioteca() biblioteca.add_book("El gran Gatsby", "F. Scott Fitzgerald", "1234567890", 3) biblioteca.add_book("Matar a un ruiseñor", "Harper Lee", "1234567891", 2) # Configurar un estudiante estudiante = Estudiante("Alice", "S1") # El estudiante toma prestado un libro"""model_inputs = TOKENIZER([input_text], return_tensors="pt").to(device)# Usar `max_new_tokens` para controlar la longitud máxima de salida.generated_ids = MODEL.generate(model_inputs.input_ids, max_new_tokens=1024, do_sample=False)[0]# Los generate_ids incluyen Prompt_ids, por lo que solo necesitamos decodificar los tokens después de Prompt_ids.output_text = TOKENIZER.decode(generated_ids[len(model_inputs.input_ids[0]):], skip_special_tokens=True)print(f"Mensaje: n{input_text}nnTexto generado: n{output_text}")
El resultado esperado es el siguiente:
Texto generado:libro = biblioteca.find_book("1234567890")if estudiante.borrow_book(libro, biblioteca):print(f"{estudiante.nombre} prestado {libro.título}")else:print(f"{estudiante.nombre } no pudo pedir prestado {libro.título}") # El estudiante devuelve un libro si estudiante.return_book(libro, biblioteca):print(f"{estudiante.nombre} devuelto {book.title}")else:print(f"{student.name} no pudo devolver {book.title}") # Listar todos los libros en la bibliotecaprint("Todos los libros en la biblioteca:")para el libro en la biblioteca. list_books():imprimir(libro)if __nombre__ == "__main__":principal()
Como miembro de la familia de Qwen2.5, Qwen2.5-Coder cuenta con el soporte de vLLM. El tutorial detallado se puede encontrar en el tutorial de Qwen. Aquí le brindamos un ejemplo simple de inferencia por lotes fuera de línea en vLLM.
from transformadores import AutoTokenizerfrom vllm import LLM, SamplingParams# Inicialice tokenizertokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-Coder-32B")# Pase los hiperparámetros de decodificación predeterminados de Qwen1.5-32B-Chat# max_tokens es para el máximo longitud para generacion.sampling_params = SamplingParams(temperature=0.7, top_p=0.8, repetition_penalty=1.05, max_tokens=1024)# Ingrese el nombre del modelo o la ruta. Puede ser GPTQ o AWQ models.llm = LLM(model="Qwen/Qwen2.5-Coder-32B")# Prepare sus indicacionesprompt = "#escriba un algoritmo de clasificación rápida.ndef quick_sort("# genere salidassalidas = llm.generate( [prompt], sampling_params)# Imprime las salidas.para la salida en salidas:prompt = salida.promptgenerated_text = salida.salidas[0].textprint(f"Pregunta: {prompt!r}, Texto generado: {generated_text!r}")
Para aumentar el rendimiento de su servicio, el servicio distribuido le ayuda a aprovechar más dispositivos GPU. Cuando se utilizan secuencias ultralargas para la inferencia, es posible que la memoria de la GPU sea insuficiente. Aquí, demostramos cómo ejecutar Qwen2.5-Coder-32B con paralelismo tensorial simplemente pasando el argumento tensor_parallel_size
.
llm = LLM(model="Qwen/Qwen2.5-Coder-32B", tensor_parallel_size=8)
También proporcionamos una interfaz Gradio para una mejor experiencia, simplemente ejecutada por:
cd demo/chatbot/# Para usuarios de Linux y Windows (¿y macOS con Intel?)python app.py # Para usuarios de macOS con Apple Silicon, Intel no es compatible, esto puede ser 20 veces más lento que RTX 4090PYTORCH_ENABLE_MPS_FALLBACK=1 python app.py
También proporcionamos una interfaz Gradio del modo artefactos:
demostración en CD/artefactos/ aplicación python.py
¡Puede especificar los argumentos --server_port
, --share
, --server_name
para satisfacer sus necesidades!
¿O probarlo sin esfuerzo en HuggingFace: 「demostración de chatbot」? 「demostración de artefactos」
Para obtener más información, consulte el Informe técnico de Qwen2.5-Coder.
Si encuentra útil nuestro trabajo, no dude en citarnos.
@artículo{hui2024qwen2, título={Qwen2. Informe técnico de 5 codificadores}, autor = {Hui, Binyuan y Yang, Jian y Cui, Zeyu y Yang, Jiaxi y Liu, Dayiheng y Zhang, Lei y Liu, Tianyu y Zhang, Jiajun y Yu, Bowen y Dang, Kai y otros}, diario={arXiv preimpresión arXiv:2409.12186}, año={2024}}@artículo{qwen2,title={Qwen2 Técnico Informe}, autor = {An Yang y Baosong Yang y Binyuan Hui y Bo Zheng y Bowen Yu y Chang Zhou y Chengpeng Li y Chengyuan Li y Dayiheng Liu y Fei Huang y Guanting Dong y Haoran Wei y Huan Lin y Jialong Tang y Jialin Wang y Jian Yang y Jianhong Tu y Jianwei Zhang y Jianxin Ma y Jin Xu y Jingren Zhou y Jinze Bai y Jinzheng He y Junyang Lin y Kai Dang y Keming Lu y Keqin Chen y Kexin Yang y Mei Li y Mingfeng Xue y Na Ni y Pei Zhang y Peng Wang y Ru Peng y Rui Men y Ruize Gao y Runji Lin y Shijie Wang y Shuai Bai y Sinan Tan y Tianhang Zhu y Tianhao Li y Tianyu Liu y Wenbin Ge y Xiaodong Deng y Xiaohuan Zhou y Xingzhang Ren y Xinyu Zhang y Xipin Wei y Xuancheng Ren y Yang Fan y Yang Yao y Yichang Zhang y Yu Wan y Yunfei Chu y Yuqiong Liu y Zeyu Cui y Zhenru Zhang y Zhihao Fan},journal={arXiv preprint arXiv:2407.10671},año={2024}}
Si está interesado en dejar un mensaje a nuestro equipo de investigación o a nuestro equipo de producto, ¡únase a nuestros grupos de Discord o WeChat!
↑ Volver arriba ↑