JobSmithManipulation Kevin Hu commited on
Commit
086a0cb
·
1 Parent(s): a694851

add huggingface model (#2624)

Browse files

### What problem does this PR solve?

#2469

### Type of change

- [x] New Feature (non-breaking change which adds functionality)

---------

Co-authored-by: Kevin Hu <[email protected]>

api/apps/llm_app.py CHANGED
@@ -155,6 +155,10 @@ def add_llm():
155
  elif factory == "LocalAI":
156
  llm_name = req["llm_name"]+"___LocalAI"
157
  api_key = "xxxxxxxxxxxxxxx"
 
 
 
 
158
 
159
  elif factory == "OpenAI-API-Compatible":
160
  llm_name = req["llm_name"]+"___OpenAI-API"
 
155
  elif factory == "LocalAI":
156
  llm_name = req["llm_name"]+"___LocalAI"
157
  api_key = "xxxxxxxxxxxxxxx"
158
+
159
+ elif factory == "HuggingFace":
160
+ llm_name = req["llm_name"]+"___HuggingFace"
161
+ api_key = "xxxxxxxxxxxxxxx"
162
 
163
  elif factory == "OpenAI-API-Compatible":
164
  llm_name = req["llm_name"]+"___OpenAI-API"
conf/llm_factories.json CHANGED
@@ -2344,6 +2344,13 @@
2344
  "tags": "LLM",
2345
  "status": "1",
2346
  "llm": []
2347
- }
 
 
 
 
 
 
 
2348
  ]
2349
  }
 
2344
  "tags": "LLM",
2345
  "status": "1",
2346
  "llm": []
2347
+ },
2348
+ {
2349
+ "name": "HuggingFace",
2350
+ "logo": "",
2351
+ "tags": "TEXT EMBEDDING",
2352
+ "status": "1",
2353
+ "llm": []
2354
+ }
2355
  ]
2356
  }
rag/llm/__init__.py CHANGED
@@ -18,7 +18,7 @@ from .chat_model import *
18
  from .cv_model import *
19
  from .rerank_model import *
20
  from .sequence2txt_model import *
21
- from .tts_model import *
22
 
23
  EmbeddingModel = {
24
  "Ollama": OllamaEmbed,
@@ -46,7 +46,8 @@ EmbeddingModel = {
46
  "SILICONFLOW": SILICONFLOWEmbed,
47
  "Replicate": ReplicateEmbed,
48
  "BaiduYiyan": BaiduYiyanEmbed,
49
- "Voyage AI": VoyageEmbed
 
50
  }
51
 
52
 
 
18
  from .cv_model import *
19
  from .rerank_model import *
20
  from .sequence2txt_model import *
21
+ from .tts_model import *
22
 
23
  EmbeddingModel = {
24
  "Ollama": OllamaEmbed,
 
46
  "SILICONFLOW": SILICONFLOWEmbed,
47
  "Replicate": ReplicateEmbed,
48
  "BaiduYiyan": BaiduYiyanEmbed,
49
+ "Voyage AI": VoyageEmbed,
50
+ "HuggingFace":HuggingFaceEmbed,
51
  }
52
 
53
 
rag/llm/chat_model.py CHANGED
@@ -1414,3 +1414,4 @@ class GoogleChat(Base):
1414
  yield ans + "\n**ERROR**: " + str(e)
1415
 
1416
  yield response._chunks[-1].usage_metadata.total_token_count
 
 
1414
  yield ans + "\n**ERROR**: " + str(e)
1415
 
1416
  yield response._chunks[-1].usage_metadata.total_token_count
1417
+
rag/llm/embedding_model.py CHANGED
@@ -678,3 +678,40 @@ class VoyageEmbed(Base):
678
  texts=text, model=self.model_name, input_type="query"
679
  )
680
  return np.array(res.embeddings), res.total_tokens
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
678
  texts=text, model=self.model_name, input_type="query"
679
  )
680
  return np.array(res.embeddings), res.total_tokens
681
+
682
+
683
+ class HuggingFaceEmbed(Base):
684
+ def __init__(self, key, model_name, base_url=None):
685
+ if not model_name:
686
+ raise ValueError("Model name cannot be None")
687
+ self.key = key
688
+ self.model_name = model_name
689
+ self.base_url = base_url or "http://127.0.0.1:8080"
690
+
691
+ def encode(self, texts: list, batch_size=32):
692
+ embeddings = []
693
+ for text in texts:
694
+ response = requests.post(
695
+ f"{self.base_url}/embed",
696
+ json={"inputs": text},
697
+ headers={'Content-Type': 'application/json'}
698
+ )
699
+ if response.status_code == 200:
700
+ embedding = response.json()
701
+ embeddings.append(embedding[0])
702
+ else:
703
+ raise Exception(f"Error: {response.status_code} - {response.text}")
704
+ return np.array(embeddings), sum([num_tokens_from_string(text) for text in texts])
705
+
706
+ def encode_queries(self, text):
707
+ response = requests.post(
708
+ f"{self.base_url}/embed",
709
+ json={"inputs": text},
710
+ headers={'Content-Type': 'application/json'}
711
+ )
712
+ if response.status_code == 200:
713
+ embedding = response.json()
714
+ return np.array(embedding[0]), num_tokens_from_string(text)
715
+ else:
716
+ raise Exception(f"Error: {response.status_code} - {response.text}")
717
+
web/src/assets/svg/llm/huggingface.svg ADDED
web/src/pages/user-setting/constants.tsx CHANGED
@@ -26,4 +26,5 @@ export const LocalLlmFactories = [
26
  'TogetherAI',
27
  'Replicate',
28
  'OpenRouter',
 
29
  ];
 
26
  'TogetherAI',
27
  'Replicate',
28
  'OpenRouter',
29
+ 'HuggingFace',
30
  ];
web/src/pages/user-setting/setting-model/constant.ts CHANGED
@@ -40,6 +40,7 @@ export const IconMap = {
40
  Anthropic: 'anthropic',
41
  'Voyage AI': 'voyage',
42
  'Google Cloud': 'google-cloud',
 
43
  };
44
 
45
  export const BedrockRegionList = [
 
40
  Anthropic: 'anthropic',
41
  'Voyage AI': 'voyage',
42
  'Google Cloud': 'google-cloud',
43
+ HuggingFace: 'huggingface',
44
  };
45
 
46
  export const BedrockRegionList = [
web/src/pages/user-setting/setting-model/ollama-modal/index.tsx CHANGED
@@ -8,6 +8,20 @@ type FieldType = IAddLlmRequestBody & { vision: boolean };
8
 
9
  const { Option } = Select;
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  const OllamaModal = ({
12
  visible,
13
  hideModal,
@@ -35,7 +49,9 @@ const OllamaModal = ({
35
 
36
  onOk?.(data);
37
  };
38
-
 
 
39
  return (
40
  <Modal
41
  title={t('addLlmTitle', { name: llmFactory })}
@@ -46,11 +62,7 @@ const OllamaModal = ({
46
  footer={(originNode: React.ReactNode) => {
47
  return (
48
  <Flex justify={'space-between'}>
49
- <a
50
- href={`https://github.com/infiniflow/ragflow/blob/main/docs/guides/deploy_local_llm.mdx`}
51
- target="_blank"
52
- rel="noreferrer"
53
- >
54
  {t('ollamaLink', { name: llmFactory })}
55
  </a>
56
  <Space>{originNode}</Space>
@@ -72,10 +84,16 @@ const OllamaModal = ({
72
  rules={[{ required: true, message: t('modelTypeMessage') }]}
73
  >
74
  <Select placeholder={t('modelTypeMessage')}>
75
- <Option value="chat">chat</Option>
76
- <Option value="embedding">embedding</Option>
77
- <Option value="rerank">rerank</Option>
78
- <Option value="image2text">image2text</Option>
 
 
 
 
 
 
79
  </Select>
80
  </Form.Item>
81
  <Form.Item<FieldType>
 
8
 
9
  const { Option } = Select;
10
 
11
+ const llmFactoryToUrlMap = {
12
+ Ollama: 'https://huggingface.co/docs/text-embeddings-inference/quick_tour',
13
+ Xinference: 'https://inference.readthedocs.io/en/latest/user_guide',
14
+ LocalAI: 'https://localai.io/docs/getting-started/models/',
15
+ 'LM-Studio': 'https://lmstudio.ai/docs/basics',
16
+ 'OpenAI-API-Compatible': 'https://platform.openai.com/docs/models/gpt-4',
17
+ TogetherAI: 'https://docs.together.ai/docs/deployment-options',
18
+ Replicate: 'https://replicate.com/docs/topics/deployments',
19
+ OpenRouter: 'https://openrouter.ai/docs',
20
+ HuggingFace:
21
+ 'https://huggingface.co/docs/text-embeddings-inference/quick_tour',
22
+ };
23
+ type LlmFactory = keyof typeof llmFactoryToUrlMap;
24
+
25
  const OllamaModal = ({
26
  visible,
27
  hideModal,
 
49
 
50
  onOk?.(data);
51
  };
52
+ const url =
53
+ llmFactoryToUrlMap[llmFactory as LlmFactory] ||
54
+ 'https://huggingface.co/docs/text-embeddings-inference/quick_tour';
55
  return (
56
  <Modal
57
  title={t('addLlmTitle', { name: llmFactory })}
 
62
  footer={(originNode: React.ReactNode) => {
63
  return (
64
  <Flex justify={'space-between'}>
65
+ <a href={url} target="_blank" rel="noreferrer">
 
 
 
 
66
  {t('ollamaLink', { name: llmFactory })}
67
  </a>
68
  <Space>{originNode}</Space>
 
84
  rules={[{ required: true, message: t('modelTypeMessage') }]}
85
  >
86
  <Select placeholder={t('modelTypeMessage')}>
87
+ {llmFactory === 'HuggingFace' ? (
88
+ <Option value="embedding">embedding</Option>
89
+ ) : (
90
+ <>
91
+ <Option value="chat">chat</Option>
92
+ <Option value="embedding">embedding</Option>
93
+ <Option value="rerank">rerank</Option>
94
+ <Option value="image2text">image2text</Option>
95
+ </>
96
+ )}
97
  </Select>
98
  </Form.Item>
99
  <Form.Item<FieldType>