args.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. """
  2. This file contains the command line arguments for the Aphrodite's
  3. OpenAI-compatible server. It is kept in a separate file for documentation
  4. purposes.
  5. """
  6. import argparse
  7. import json
  8. import ssl
  9. from aphrodite.common.utils import FlexibleArgumentParser
  10. from aphrodite.endpoints.openai.serving_engine import (LoRAModulePath,
  11. PromptAdapterPath)
  12. from aphrodite.engine.args_tools import AsyncEngineArgs
  13. class LoRAParserAction(argparse.Action):
  14. def __call__(self, parser, namespace, values, option_string=None):
  15. lora_list = []
  16. for item in values:
  17. if item in [None, '']: # Skip if item is None or empty string
  18. continue
  19. if '=' in item and ',' not in item: # Old format: name=path
  20. name, path = item.split('=')
  21. lora_list.append(LoRAModulePath(name, path))
  22. else: # Assume JSON format
  23. try:
  24. lora_dict = json.loads(item)
  25. lora = LoRAModulePath(**lora_dict)
  26. lora_list.append(lora)
  27. except json.JSONDecodeError:
  28. parser.error(
  29. f"Invalid JSON format for --lora-modules: {item}")
  30. except TypeError as e:
  31. parser.error(
  32. f"Invalid fields for --lora-modules: {item} - {str(e)}"
  33. )
  34. setattr(namespace, self.dest, lora_list)
  35. class PromptAdapterParserAction(argparse.Action):
  36. def __call__(self, parser, namespace, values, option_string=None):
  37. adapter_list = []
  38. for item in values:
  39. name, path = item.split('=')
  40. adapter_list.append(PromptAdapterPath(name, path))
  41. setattr(namespace, self.dest, adapter_list)
  42. def make_arg_parser(parser: FlexibleArgumentParser) -> FlexibleArgumentParser:
  43. parser.add_argument("--host", type=str, default=None, help="host name")
  44. parser.add_argument("--port", type=int, default=2242, help="port number")
  45. parser.add_argument(
  46. "--uvicorn-log-level",
  47. type=str,
  48. default="info",
  49. choices=['debug', 'info', 'warning', 'error', 'critical', 'trace'],
  50. help="log level for uvicorn")
  51. parser.add_argument("--allow-credentials",
  52. action="store_true",
  53. help="allow credentials")
  54. parser.add_argument("--allowed-origins",
  55. type=json.loads,
  56. default=["*"],
  57. help="allowed origins")
  58. parser.add_argument("--allowed-methods",
  59. type=json.loads,
  60. default=["*"],
  61. help="allowed methods")
  62. parser.add_argument("--allowed-headers",
  63. type=json.loads,
  64. default=["*"],
  65. help="allowed headers")
  66. parser.add_argument("--api-keys",
  67. type=str,
  68. default=None,
  69. help="If provided, the server will require this key "
  70. "to be presented in the header.")
  71. parser.add_argument("--admin-key",
  72. type=str,
  73. default=None,
  74. help="If provided, the server will require this key "
  75. "to be presented in the header for admin operations.")
  76. parser.add_argument(
  77. "--lora-modules",
  78. type=str,
  79. default=None,
  80. nargs='+',
  81. action=LoRAParserAction,
  82. help="LoRA module configurations in either 'name=path' format"
  83. "or JSON format. "
  84. "Example (old format): 'name=path' "
  85. "Example (new format): "
  86. "'{\"name\": \"name\", \"local_path\": \"path\", "
  87. "\"base_model_name\": \"id\"}'")
  88. parser.add_argument(
  89. "--prompt-adapters",
  90. type=str,
  91. default=None,
  92. nargs='+',
  93. action=PromptAdapterParserAction,
  94. help="Prompt adapter configurations in the format name=path. "
  95. "Multiple adapters can be specified.")
  96. parser.add_argument("--chat-template",
  97. type=str,
  98. default=None,
  99. help="The file path to the chat template, "
  100. "or the template in single-line form "
  101. "for the specified model")
  102. parser.add_argument("--response-role",
  103. type=str,
  104. default="assistant",
  105. help="The role name to return if "
  106. "`request.add_generation_prompt=true`.")
  107. parser.add_argument("--ssl-keyfile",
  108. type=str,
  109. default=None,
  110. help="The file path to the SSL key file")
  111. parser.add_argument("--ssl-certfile",
  112. type=str,
  113. default=None,
  114. help="The file path to the SSL cert file")
  115. parser.add_argument("--ssl-ca-certs",
  116. type=str,
  117. default=None,
  118. help="The CA certificates file")
  119. parser.add_argument(
  120. "--ssl-cert-reqs",
  121. type=int,
  122. default=int(ssl.CERT_NONE),
  123. help="Whether client certificate is required (see stdlib ssl module's)"
  124. )
  125. parser.add_argument(
  126. "--root-path",
  127. type=str,
  128. default=None,
  129. help="FastAPI root_path when app is behind a path based routing proxy")
  130. parser.add_argument(
  131. "--middleware",
  132. type=str,
  133. action="append",
  134. default=[],
  135. help="Additional ASGI middleware to apply to the app. "
  136. "We accept multiple --middleware arguments. "
  137. "The value should be an import path. "
  138. "If a function is provided, Aphrodite will add it to the server "
  139. "using @app.middleware('http'). "
  140. "If a class is provided, Aphrodite will add it to the server "
  141. "using app.add_middleware(). ")
  142. parser.add_argument(
  143. "--launch-kobold-api",
  144. action="store_true",
  145. help="Launch the Kobold API server alongside the OpenAI server")
  146. parser.add_argument("--max-log-len",
  147. type=int,
  148. default=0,
  149. help="Max number of prompt characters or prompt "
  150. "ID numbers being printed in log."
  151. "\n\nDefault: 0")
  152. parser.add_argument(
  153. "--return-tokens-as-token-ids",
  154. action="store_true",
  155. help="When --max-logprobs is specified, represents single tokens as"
  156. "strings of the form 'token_id:{token_id}' so that tokens that"
  157. "are not JSON-encodable can be identified.")
  158. parser.add_argument(
  159. "--disable-frontend-multiprocessing",
  160. action="store_true",
  161. help="If specified, will run the OpenAI frontend server in the same "
  162. "process as the model serving engine.")
  163. parser.add_argument(
  164. "--allow-inline-model-loading",
  165. action="store_true",
  166. help="If specified, will allow the model to be switched inline "
  167. "in the same process as the OpenAI frontend server.")
  168. parser.add_argument(
  169. "--enable-auto-tool-choice",
  170. action="store_true",
  171. default=False,
  172. help=
  173. "Enable auto tool choice for supported models. Use --tool-call-parser"
  174. "to specify which parser to use")
  175. parser.add_argument(
  176. "--tool-call-parser",
  177. type=str,
  178. choices=["mistral", "hermes"],
  179. default=None,
  180. help=
  181. "Select the tool call parser depending on the model that you're using."
  182. " This is used to parse the model-generated tool call into OpenAI API "
  183. "format. Required for --enable-auto-tool-choice.")
  184. parser = AsyncEngineArgs.add_cli_args(parser)
  185. return parser
  186. def create_parser_for_docs() -> FlexibleArgumentParser:
  187. parser_for_docs = FlexibleArgumentParser(
  188. prog="-m aphrodite.endpoints.openai.api_server")
  189. return make_arg_parser(parser_for_docs)