merligus commited on
Commit
314bc09
·
1 Parent(s): 26d280a

QWEN Chat model for free

Browse files
Files changed (7) hide show
  1. .gitignore +97 -0
  2. QWEN/__init__.py +144 -0
  3. README.md +19 -0
  4. install.sh +50 -0
  5. query.py +31 -0
  6. requirements.txt +6 -0
  7. run.sh +18 -0
.gitignore ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # skin_color
2
+ .ipynb_checkpoints
3
+ __pycache__/
4
+ tmp/
5
+ flask_session/
6
+ *.sarif
7
+ *.xlsx
8
+ *.h5
9
+
10
+ # Byte-compiled / optimized / DLL files
11
+ __pycache__/
12
+ *.py[cod]
13
+ *$py.class
14
+
15
+ *.DS_Store
16
+
17
+ # Distribution / packaging
18
+ .Python
19
+ build/
20
+ develop-eggs/
21
+ dist/
22
+ downloads/
23
+ eggs/
24
+ .eggs/
25
+ lib/
26
+ lib64/
27
+ parts/
28
+ sdist/
29
+ var/
30
+ wheels/
31
+ *.egg-info/
32
+ .installed.cfg
33
+ *.egg
34
+ MANIFEST
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+
52
+ # Sphinx documentation
53
+ docs/_build/
54
+
55
+ # PyBuilder
56
+ target/
57
+
58
+ # Jupyter Notebook
59
+ .ipynb_checkpoints
60
+
61
+ # pyenv
62
+ .python-version
63
+
64
+ # PyTorch weights
65
+ *.tar
66
+ *.pth
67
+ *.pt
68
+ *.torch
69
+ *.gz
70
+ Untitled.ipynb
71
+ Testing notebook.ipynb
72
+
73
+ # Root dir exclusions
74
+ /*.csv
75
+ /*.yaml
76
+ /*.json
77
+ /*.jpg
78
+ /*.png
79
+ /*.zip
80
+ /*.tar.*
81
+ *.jpg
82
+ *.png
83
+ *.avi
84
+ *.mp4
85
+ *.svg
86
+
87
+ .mypy_cache/
88
+ .vscode/
89
+ .idea
90
+
91
+ output/
92
+ input/
93
+
94
+ !test/*
95
+
96
+ node_modules/
97
+ package-lock.json
QWEN/__init__.py ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional, List, Any, Dict, Iterator
2
+ from langchain_core.language_models import BaseChatModel
3
+ from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage
4
+ from langchain_core.outputs import ChatGeneration, ChatResult
5
+ from pydantic import PrivateAttr
6
+
7
+ # used for qwen inference
8
+ import torch
9
+ from transformers import AutoModelForCausalLM, AutoTokenizer
10
+
11
+
12
+ class ChatQWEN(BaseChatModel):
13
+ """A custom chat model that invoke Qwen2.5-1.5B-Instruct.
14
+
15
+ Example:
16
+
17
+ .. code-block:: python
18
+
19
+ model = ChatQWEN()
20
+ result = model.invoke([HumanMessage(content="hello")])
21
+ result = model.batch([[HumanMessage(content="hello")],
22
+ [HumanMessage(content="world")]])
23
+ """
24
+
25
+ model_name: str = "Qwen/Qwen2.5-1.5B-Instruct"
26
+ """The name of the model"""
27
+ # other params
28
+ temperature: float = 0.7
29
+ max_new_tokens: int = 512
30
+ device_map: str = "auto"
31
+
32
+ # private attributes
33
+ _model: Any = PrivateAttr()
34
+ _tokenizer: Any = PrivateAttr()
35
+ """The model to call"""
36
+
37
+ def __init__(self, **kwargs):
38
+ super().__init__(**kwargs)
39
+
40
+ # load qwen
41
+ self._tokenizer = AutoTokenizer.from_pretrained(
42
+ self.model_name, trust_remote_code=True
43
+ )
44
+
45
+ self._model = AutoModelForCausalLM.from_pretrained(
46
+ self.model_name,
47
+ device_map=self.device_map,
48
+ torch_dtype=torch.bfloat16,
49
+ offload_folder=None,
50
+ low_cpu_mem_usage=True,
51
+ trust_remote_code=True,
52
+ ).eval()
53
+
54
+ # Adicione isto após carregar o modelo
55
+ print(f"GPU memory used: {torch.cuda.memory_allocated()/1024**3:.2f} GB")
56
+ print(f"GPU memory reserved: {torch.cuda.memory_reserved()/1024**3:.2f} GB")
57
+
58
+ def _convert_message_to_dict(self, message: BaseMessage) -> dict:
59
+ """Messages from LangChain to format expected by QWEN"""
60
+ if isinstance(message, HumanMessage):
61
+ return {"role": "user", "content": message.content}
62
+ elif isinstance(message, AIMessage):
63
+ return {"role": "assistant", "content": message.content}
64
+ elif isinstance(message, SystemMessage):
65
+ return {"role": "system", "content": message.content}
66
+ else:
67
+ raise ValueError(f"Message type not supported: {type(message)}")
68
+
69
+ def qwen(self, messages):
70
+ # make the prompt in a way to the model understand
71
+ text = self._tokenizer.apply_chat_template(
72
+ messages, tokenize=False, add_generation_prompt=True
73
+ )
74
+ model_inputs = self._tokenizer([text], return_tensors="pt").to(
75
+ self._model.device
76
+ )
77
+
78
+ # generate the qwen text
79
+ with torch.no_grad():
80
+ generated_ids = self._model.generate(
81
+ **model_inputs,
82
+ max_new_tokens=self.max_new_tokens,
83
+ temperature=self.temperature,
84
+ )
85
+ generated_ids = [
86
+ output_ids[len(input_ids) :]
87
+ for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
88
+ ]
89
+
90
+ # get the response of the LLM
91
+ response = self._tokenizer.batch_decode(
92
+ generated_ids, skip_special_tokens=True
93
+ )[0]
94
+
95
+ return response
96
+
97
+ def _generate(
98
+ self,
99
+ messages: List[BaseMessage],
100
+ stop: Optional[List[str]] = None,
101
+ run_manager: Optional[Any] = None,
102
+ **kwargs: Any,
103
+ ) -> ChatResult:
104
+ """
105
+ Args:
106
+ messages: the prompt composed of a list of messages.
107
+ """
108
+ # parse the messages to feed qwen
109
+ formatted_messages = [self._convert_message_to_dict(msg) for msg in messages]
110
+
111
+ # call qwen
112
+ qwen_response = self.qwen(formatted_messages)
113
+
114
+ # process the stop tokens
115
+ if stop:
116
+ for stop_word in stop:
117
+ qwen_response = qwen_response.split(stop_word)[0]
118
+
119
+ # message type update
120
+ message = AIMessage(content=qwen_response.strip())
121
+
122
+ # return
123
+ generation = ChatGeneration(message=message, text=qwen_response.strip())
124
+ return ChatResult(generations=[generation])
125
+
126
+ @property
127
+ def _llm_type(self) -> str:
128
+ """Get the type of language model used by this chat model."""
129
+ return "qwen-chat-model"
130
+
131
+ @property
132
+ def _identifying_params(self) -> Dict[str, Any]:
133
+ """Return a dictionary of identifying parameters.
134
+
135
+ This information is used by the LangChain callback system, which
136
+ is used for tracing purposes make it possible to monitor LLMs.
137
+ """
138
+ return {
139
+ # The model name allows users to specify custom token counting
140
+ # rules in LLM monitoring applications (e.g., in LangSmith users
141
+ # can provide per token pricing for their model and monitor
142
+ # costs for the given LLM.)
143
+ "model_name": self.model_name,
144
+ }
README.md ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Book Reader
2
+
3
+ ## Install
4
+
5
+ Run the bash script to install the conda environments:
6
+
7
+ ```sh
8
+ bash install.sh
9
+ ```
10
+
11
+ ## Run
12
+
13
+ 1. Run the bash script to download the models and run the APIs.
14
+
15
+ ```sh
16
+ bash run.sh
17
+ ```
18
+
19
+ ## Example
install.sh ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Path to the conda executable
4
+ CONDA_PATH=$(which conda)
5
+
6
+ # Check if conda is installed
7
+ if [ -z "$CONDA_PATH" ]; then
8
+ echo "Conda could not be found. Please install conda first."
9
+ exit
10
+ fi
11
+
12
+ # Initialize conda
13
+ eval "$($CONDA_PATH shell.bash hook)"
14
+
15
+ # List of conda environments to activate
16
+ ENVIRONMENTS=("specialist:3.11")
17
+
18
+ # Loop through each environment and activate it
19
+ for ENV_NAME_VERSION in "${ENVIRONMENTS[@]}"; do
20
+ # get environment name and python version
21
+ IFS=':' read -r ENV_NAME PYTHON_VERSION <<< "$ENV_NAME_VERSION"
22
+
23
+ if { conda env list | grep $ENV_NAME; } >/dev/null 2>&1; then
24
+ echo "$ENV_NAME already exists."
25
+ else
26
+ # Create the conda environment
27
+ echo "Creating conda environment: $ENV_NAME with Python version: $PYTHON_VERSION"
28
+ conda create -n $ENV_NAME python=$PYTHON_VERSION -y
29
+ fi
30
+ # Activate the conda environment
31
+ echo "Activating conda environment..."
32
+ conda activate $ENV_NAME
33
+
34
+ # Install the requirements from requirements.txt
35
+ if [ -f requirements.txt ]; then
36
+ echo "Installing requirements from requirements.txt..."
37
+ pip install -r requirements.txt
38
+ else
39
+ echo "requirements.txt file not found. Please provide the file."
40
+ exit
41
+ fi
42
+
43
+ echo "Conda environment '$ENV_NAME' is ready."
44
+
45
+ echo "Deactivating conda environment..."
46
+ conda deactivate
47
+ cd ..
48
+ done
49
+
50
+ echo "Installation complete."
query.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # chat
2
+ from QWEN import ChatQWEN
3
+ from langchain_core.prompts import ChatPromptTemplate
4
+
5
+ # prompt chat
6
+ prompt = ChatPromptTemplate(
7
+ [
8
+ (
9
+ "system",
10
+ "You are Qwen, created by Alibaba Cloud. You are a helpful assistant that translates {input_language} to {output_language}.",
11
+ ),
12
+ ("human", "{input}"),
13
+ ]
14
+ )
15
+
16
+ # model creation
17
+ llm = ChatQWEN()
18
+
19
+ # pipeline
20
+ chain = prompt | llm
21
+
22
+ # query
23
+ print(
24
+ chain.invoke(
25
+ {
26
+ "input_language": "English",
27
+ "output_language": "German",
28
+ "input": "I love programming",
29
+ }
30
+ ).content
31
+ )
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ langchain-deepseek==0.1.2
2
+ torch==2.4.1
3
+ triton==3.0.0
4
+ transformers==4.46.3
5
+ safetensors==0.4.5
6
+ accelerate>=0.26.0
run.sh ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Path to the conda executable
4
+ CONDA_PATH=$(which conda)
5
+
6
+ # Check if conda is installed
7
+ if [ -z "$CONDA_PATH" ]; then
8
+ echo "Conda could not be found. Please install conda first."
9
+ exit
10
+ fi
11
+
12
+ # Initialize conda
13
+ eval "$($CONDA_PATH shell.bash hook)"
14
+
15
+ conda activate specialist
16
+ python query.py
17
+ conda deactivate
18
+ echo "Completed."