Parse a time string into a :class:`Time` instance. A time string is a numerical value followed by the value of a :class:`TimeUnit` enum. For example: >>> Time.from_timestring("5ep") # describes 5 epochs. Time(5, TimeUnit.EPOCH) >>> Time.from_timestring("3e4tok") #
(cls, timestring: str)
| 422 | |
| 423 | @classmethod |
| 424 | def from_timestring(cls, timestring: str) -> Time: |
| 425 | """Parse a time string into a :class:`Time` instance. |
| 426 | |
| 427 | A time string is a numerical value followed by the value of a :class:`TimeUnit` enum. For example: |
| 428 | |
| 429 | >>> Time.from_timestring("5ep") # describes 5 epochs. |
| 430 | Time(5, TimeUnit.EPOCH) |
| 431 | >>> Time.from_timestring("3e4tok") # describes 30,000 tokens. |
| 432 | Time(30000, TimeUnit.TOKEN) |
| 433 | >>> Time.from_timestring("0.5dur") # describes 50% of the training process. |
| 434 | Time(0.5, TimeUnit.DURATION) |
| 435 | |
| 436 | Returns: |
| 437 | Time: An instance of :class:`Time`. |
| 438 | """ |
| 439 | # Handle TimeDelta matching first |
| 440 | try: |
| 441 | return Time.from_timedelta(timestring) |
| 442 | except ValueError: |
| 443 | pass |
| 444 | |
| 445 | match = _TIME_STR_REGEX.findall(timestring) |
| 446 | if len(match) != 1: |
| 447 | raise ValueError(f'Invalid time string: {timestring}') |
| 448 | match = match[0] |
| 449 | match = [x for x in match if x != ''] |
| 450 | assert len(match) == 2, 'each match should have a number followed by the key' |
| 451 | value = match[0] |
| 452 | unit = TimeUnit(match[1]) |
| 453 | value = float(value) # always parsing first as float b/c it could be scientific notation |
| 454 | if unit != TimeUnit.DURATION: |
| 455 | if int(value) != value: |
| 456 | raise TypeError(f'value {value} is not an integer. Units {unit} require integer values.') |
| 457 | value = int(value) |
| 458 | return cls(value, unit) |
| 459 | |
| 460 | |
| 461 | class Timestamp(Serializable): |