docstr: Convert spec to CpuResource.
  
  spec can be a float, int or string.
  - 1.0 -> 1.0
  - 1 -> 1.0
  - "1" -> 1.0
  - "10m" -> 0.01
docstr_tok: ["Convert","spec","to","CpuResource",".","spec","can","be","a","float",",","int","or","string",".","-","1.0","-",">","1.0","-","1","-",">","1.0","-","``","1","''","-",">","1.0","-","``","10m","''","-",">","0.01"]
code: def from_spec(cls, spec: t.Any) -> float:
      """
      Convert spec to CpuResource.
  
      spec can be a float, int or string.
      - 1.0 -> 1.0
      - 1 -> 1.0
      - "1" -> 1.0
      - "10m" -> 0.01
      """
      if not isinstance(spec, (int, float, str)):
          raise TypeError("cpu must be int, float or str")
  
      if isinstance(spec, (int, float)):
          return float(spec)
  
      milli_match = re.match("([0-9]+)m", spec)
      if milli_match:
          return float(milli_match[1]) / 1000.0
  
      try:
          return float(spec)
      except ValueError:
          raise BentoMLConfigException(
              f"Invalid CPU resource limit '{spec}'. "
          )
  
imports: from __future__ import annotations
  import functools
  import logging
  import math
  import os
  import re
  import typing
  from abc import ABC
  from abc import abstractmethod
  import psutil
  from ..exceptions import BentoMLConfigException
label_desc: Use image node_id 1 for calling the CpuResource obj's underlying member method code with example usage: obj.from_spec(cls, spec) and returns: float, unknown, float